text:
package entidades;
// Generated Jul 4, 2016 12:16:49 PM by Hibernate Tools 4.0.0.Final

import java.util.Date;

/**
 * Opciones generated by hbm2java
 */
public class Opciones implements java.io.Serializable {

	private Integer idOpcion;
	private Permisos permisos;
	private String opcion;
	private Integer opcionContenedora;
	private String orden;
	private String tituloMenu;
	private String imagen;
	private String url;
	private Estados estados;
	private Date fechaCreacion;
	private int usuarioCrea;
	private Date fechaModificacion;
	private Integer usuarioModifica;

	public Opciones() {
	}

	public Opciones(String opcion, String orden, String tituloMenu, Estados estados, Date fechaCreacion, int usuarioCrea) {
		this.opcion = opcion;
		this.orden = orden;
		this.tituloMenu = tituloMenu;
		this.estados = estados;
		this.fechaCreacion = fechaCreacion;
		this.usuarioCrea = usuarioCrea;
	}

	public Opciones(Permisos permisos, String opcion, Integer opcionContenedora, String orden, String tituloMenu,
			String imagen, String url, Estados estados, Date fechaCreacion, int usuarioCrea, Date fechaModificacion,
			Integer usuarioModifica) {
		this.permisos = permisos;
		this.opcion = opcion;
		this.opcionContenedora = opcionContenedora;
		this.orden = orden;
		this.tituloMenu = tituloMenu;
		this.imagen = imagen;
		this.url = url;
		this.estados = estados;
		this.fechaCreacion = fechaCreacion;
		this.usuarioCrea = usuarioCrea;
		this.fechaModificacion = fechaModificacion;
		this.usuarioModifica = usuarioModifica;
	}

	public Integer getIdOpcion() {
		return this.idOpcion;
	}

	public void setIdOpcion(Integer idOpcion) {
		this.idOpcion = idOpcion;
	}

	public Permisos getPermisos() {
		return this.permisos;
	}

	public void setPermisos(Permisos permisos) {
		this.permisos = permisos;
	}

	public String getOpcion() {
		return this.opcion;
	}

	public void setOpcion(String opcion) {
		this.opcion = opcion;
	}

	public Integer getOpcionContenedora() {
		return this.opcionContenedora;
	}

	public void setOpcionContenedora(Integer opcionContenedora) {
		this.opcionContenedora = opcionContenedora;
	}

	public String getOrden() {
		return this.orden;
	}

	public void setOrden(String orden) {
		this.orden = orden;
	}

	public String getTituloMenu() {
		return this.tituloMenu;
	}

	public void setTituloMenu(String tituloMenu) {
		this.tituloMenu = tituloMenu;
	}

	public String getImagen() {
		return this.imagen;
	}

	public void setImagen(String imagen) {
		this.imagen = imagen;
	}

	public String getUrl() {
		return this.url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public Estados getEstados() {
		return this.estados;
	}

	public void setEstados(Estados estados) {
		this.estados = estados;
	}

	public Date getFechaCreacion() {
		return this.fechaCreacion;
	}

	public void setFechaCreacion(Date fechaCreacion) {
		this.fechaCreacion = fechaCreacion;
	}

	public int getUsuarioCrea() {
		return this.usuarioCrea;
	}

	public void setUsuarioCrea(int usuarioCrea) {
		this.usuarioCrea = usuarioCrea;
	}

	public Date getFechaModificacion() {
		return this.fechaModificacion;
	}

	public void setFechaModificacion(Date fechaModificacion) {
		this.fechaModificacion = fechaModificacion;
	}

	public Integer getUsuarioModifica() {
		return this.usuarioModifica;
	}

	public void setUsuarioModifica(Integer usuarioModifica) {
		this.usuarioModifica = usuarioModifica;
	}

}


text:
class Scheduler;

class CLIENT_API SchedulerModel : public QAbstractTableModel
{
    Q_OBJECT
    Q_ENUMS(Roles Mode)
    Q_PROPERTY(Scheduler *scheduler READ scheduler WRITE setScheduler NOTIFY schedulerChanged)
    Q_PROPERTY(int updateInterval READ updateInterval WRITE setUpdateInterval NOTIFY updateIntervalChanged)

public:
    SchedulerModel(QObject *parent = 0);
    ~SchedulerModel();

    enum Roles
    {
        NameRole = Qt::UserRole + 1,
        IdRole,
        NextRunRole,
        TimeLeftRole,
        TypeRole
    };

    enum Mode
    {
    };

    void setScheduler(Scheduler *scheduler);
    Scheduler *scheduler() const;

    void setUpdateInterval(int ms);
    int updateInterval() const;

    Q_INVOKABLE void reset();
    Q_INVOKABLE QVariant get(int index) const;

    // QAbstractTableModel overrides
    QHash<int, QByteArray> roleNames() const;

    int rowCount(const QModelIndex &parent) const;
    int columnCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;

signals:
    void schedulerChanged();
    void updateIntervalChanged();

protected:
    class Private;
    Private *d;
};

#endif // SCHEDULERMODEL_H

redpajama_set_name: RedPajamaGithub


text:
from django.contrib import messages
from django.views.generic.edit import DeleteView

from .permission_mixins import SuperUserCheckMixin

class DeleteViewMixin(SuperUserCheckMixin, DeleteView):
    template_name = "delete.html"
    success_message = "Item was successfully deleted"

    def delete(self, request, *args, **kwargs):
        messages.success(self.request, self.success_message)
        return super(DeleteViewMixin, self).delete(request, *args, **kwargs)


text:
#include <string>
#include <vector>

#include <boost/test/unit_test.hpp>

#include <uhttp/HTTP.h>

using namespace uHTTP;

BOOST_AUTO_TEST_CASE(MutexTests)
{
  Mutex *mutex = new Mutex();
  BOOST_CHECK_EQUAL(mutex->lock(), true);
  BOOST_CHECK_EQUAL(mutex->unlock(), true);
  delete mutex;
}


text:
<?php

/**
 * Report incoming broken links
 */

class SearchQueryReport extends SS_Report {

	public function title() {
		return _t('FourOhFourLogger.SEARCHQUERYREPORT',"Search usage report");
	}

	public function parameterFields() {
		return false;
	}

	public function sourceRecords($params, $sort, $limit) {

		return SearchLog::get();
	}

	public function columns() {

		$fields = array(
			"Count" => array(
				"title" => _t('FourOhFourLogger.HitCount', 'Amount of hits')
			),
			"Query" => array(
				"title" => _t('FourOhFourLogger.SearchTerm', "Search term")
			),
			"LastEdited" => array(
				"title" => _t('FourOhFourLogger.LastHit', 'Most recent hit'),
				'casting' => 'SS_Datetime->Full'
			)
		);

		return $fields;
	}
}


text:
#include <QDebug>
#include <QGraphicsWidget>
#include <QGraphicsLinearLayout>
#include <QSettings>

#include <MAction>
#include <MButton>
#include <MPannableViewport>
#include <MWidgetController>
#include <MList>
#include <MTextEdit>
#include <MDialog>

#include "playlists.h"
#include "appwindow.h"
#include "playlistsmodel.h"
#include "artistitemcreator.h"
#include "searchengine.h"

Playlists::Playlists(MStylableWidget * parent):MStylableWidget(parent)
{
    qDebug() << "Playlists::Playlists";

    settings.beginGroup(PLAYLIST_SETTINGS_GROUP);

    setObjectName("Playlists");
    setViewType("background");
    setContentsMargins(0, 0, 0, 0);

    QGraphicsLinearLayout *layout =
        new QGraphicsLinearLayout(Qt::Vertical, this);
    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);

    MPannableViewport *viewport = new MPannableViewport(this);
    MWidgetController *container = new MWidgetController;
    container->setViewType("background");
    container->setObjectName("PlaylistContainer");
    container->setContentsMargins(0, 0, 0, 0);
    viewport->setObjectName("PlaylistListing");

    listLayout = new QGraphicsLinearLayout(Qt::Vertical, container);
    listLayout->setSpacing(0);
    listLayout->setContentsMargins(0, 0, 0, 0);

    viewport->setWidget(container);
    layout->addItem(viewport);

    list = new MList(this);
    ArtistItemCreator *itemCreator = new ArtistItemCreator();
    list->setCellCreator(itemCreator);
    model = new PlaylistsModel();
    list->setItemModel(model);

    MAction *action = new MAction("Play", list);
    action->setLocation(MAction::ObjectMenuLocation);
    list->addAction(action);
    connect(action, SIGNAL(triggered()), this,
            SLOT(playPlaylistFromObjectMenu()));

    action = new MAction("Add to play queue", list);
    action->setLocation(MAction::ObjectMenuLocation);
    list->addAction(action);
    connect(action, SIGNAL(triggered()), this,
            SLOT(loadPlaylistFromObjectMenu()));

    action = new MAction("New playlist", list);
    action->setLocation(MAction::ObjectMenuLocation);
    list->addAction(action);
    connect(action, SIGNAL(triggered()), this,
            SLOT(newPlaylistFromObjectMenu()));

    action = new MAction("Delete playlist", list);
    action->setLocation(MAction::ObjectMenuLocation);
    list->addAction(action);
    connect(action, SIGNAL(triggered()), this,
            SLOT(deletePlaylistFromObjectMenu()));

    connect(list, SIGNAL(itemClicked(QModelIndex)), this,
            SLOT(openPlaylist(QModelIndex)));
    connect(list, SIGNAL(itemLongTapped(QModelIndex)), this,
            SLOT(itemLongTapped(QModelIndex)));

    listLayout->addItem(list);

/*
    QStringList keys = settings.allKeys();
    for (QStringList::const_iterator iter = keys.begin(); iter != keys.end(); iter++)
    {
	MButton *b = new MButton(*iter);
	b->setObjectName("PlaylistItem");
	listLayout->addItem(b);

	MAction* openAction = new MAction (tr("Open"), b);
	openAction->setLocation(MAction::ObjectMenuLocation);
	connect(openAction, SIGNAL(triggered()), this, SLOT(openPlaylist()));
	b->addAction(openAction);

	MAction* shuffleAction = new MAction (tr("Shuffle"), b);
	shuffleAction->setLocation(MAction::ObjectMenuLocation);
	connect(shuffleAction, SIGNAL(triggered()), this, SLOT(shufflePlaylist()));
	b->addAction(shuffleAction);

	MAction* playAction = new MAction (QString(tr("Play %1")).arg(*iter), b);
	playAction->setLocation(MAction::ObjectMenuLocation);
	connect(playAction, SIGNAL(triggered()), this, SLOT(playPlaylist()));
	b->addAction(playAction);

	MAction* deleteAction = new MAction (QString(tr("Delete %1")).arg(*iter), b);
	deleteAction->setLocation(MAction::ObjectMenuLocation);
	connect(deleteAction, SIGNAL(triggered()), this, SLOT(deletePlaylist()));
	b->addAction(deleteAction);

    }
*/
}

Playlists::~Playlists()
{
    qDebug() << "Playlist::~Playlist";
    settings.endGroup();
}

void Playlists::openPlaylist(const QModelIndex & index)
{
    qDebug() << "Playlist::openPlaylist" << index.data(Qt::DisplayRole).toString();

    QString playlistName = index.data(Qt::DisplayRole).toString();
    QVector < QStringList > items;
    SearchEngine::getPlaylistItems(index.data(Qt::DisplayRole).toString(), items);

    for (QVector < QStringList >::iterator iter = items.begin();
         iter != items.end(); iter++) {
         QStringList data = *iter;
         uris << data[0];
    }

//    qDebug() << items << uris;
    AppWindow::instance()->showPlaylist(playlistName, uris);
}

void Playlists::playPlaylistFromObjectMenu()
{
    qDebug() << "Playlists::playPlaylistFromObjectMenu" << longTappedIndex.data(Qt::DisplayRole);
    AppWindow::instance()->playPlaylist(longTappedIndex.data(Qt::DisplayRole).toString());
}

void Playlists::loadPlaylistFromObjectMenu()
{
    qDebug() << "Playlists::loadPlaylistFromObjectMenu" << longTappedIndex.data(Qt::DisplayRole);
    AppWindow::instance()->loadPlaylist(longTappedIndex.data(Qt::DisplayRole).toString());
}

void Playlists::deletePlaylist()
{
    MButton *b = static_cast < MButton * >(sender()->parent());

    qDebug() << "Playlist::deletePlaylist " << b->text();

    settings.remove(b->text());
    settings.sync();

    listLayout->removeItem(b);
    b->deleteLater();
}

void Playlists::newPlaylistFromObjectMenu()
{
    qDebug() << "Playlist::newPlaylistFromObjectMenu";

    showDialog();
}

void Playlists::deletePlaylistFromObjectMenu()
{
    qDebug() << "Playlist::deletePlaylistFromObjectMenu";

    if (longTappedIndex.isValid())
        model->deletePlaylist(longTappedIndex);
}

void Playlists::showDialog()
{
    MWidget *centralWidget = new MWidget;
    QGraphicsLinearLayout *layout =
        new QGraphicsLinearLayout(Qt::Vertical);

    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);

    MLabel *label = new MLabel("Playlist Name", centralWidget);
    playlistEdit = new MTextEdit(MTextEditModel::SingleLine,
                                 QString(), centralWidget);
    playlistEdit->setObjectName("playlistEdit");
    centralWidget->setLayout(layout);
    layout->addItem(label);
    layout->addItem(playlistEdit);

    MDialog *dialog =
        new MDialog("Please enter your name",
                    M::OkButton | M::CancelButton);
    dialog->setObjectName("Dialog");
    dialog->setCentralWidget(centralWidget);

    connect(dialog, SIGNAL(accepted()), this, SLOT(newPlaylist()));
//    connect(dialog, SIGNAL(rejected()), this, SLOT(test()));
//
    dialog->appear(MSceneWindow::DestroyWhenDone);
}

void Playlists::newPlaylist()
{
    qDebug() << "Playlist::newPlaylist" << playlistEdit->text();
    QVector < QStringList > items;
    model->newPlaylist(playlistEdit->text());
}

void Playlists::itemLongTapped(const QModelIndex & index)
{
    qDebug() << "Playlist::itemLongTapped" << index.row();

    longTappedIndex = index;
}


text:
try: #pragma: no cover
    from .tw2widgets.widgets import *
except ImportError: #pragma: no cover
    from .tw1widgets.widgets import *

try: #pragma: no cover
    from tw2.forms import CalendarBase
except: #pragma: no cover
    class CalendarBase(object):
        pass


text:
package engine

import (
	"context"
	"errors"
	"testing"

	topodatapb "vitess.io/vitess/go/vt/proto/topodata"

	"vitess.io/vitess/go/vt/vtgate/evalengine"

	"github.com/stretchr/testify/require"

	"vitess.io/vitess/go/sqltypes"
	"vitess.io/vitess/go/vt/vtgate/vindexes"

	querypb "vitess.io/vitess/go/vt/proto/query"
	vschemapb "vitess.io/vitess/go/vt/proto/vschema"
)

func TestInsertUnsharded(t *testing.T) {
	ins := NewQueryInsert(
		InsertUnsharded,
		&vindexes.Keyspace{
			Name:    "ks",
			Sharded: false,
		},
		"dummy_insert",
	)

	vc := newDMLTestVCursor("0")
	vc.results = []*sqltypes.Result{{
		InsertID: 4,
	}}

	result, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		`ResolveDestinations ks [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard ks.0: dummy_insert {} true true`,
	})
	expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 4})

	// Failure cases
	vc = &loggingVCursor{shardErr: errors.New("shard_error")}
	_, err = ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.EqualError(t, err, `shard_error`)

	vc = &loggingVCursor{}
	_, err = ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.EqualError(t, err, `Keyspace does not have exactly one shard: []`)
}

func TestInsertUnshardedGenerate(t *testing.T) {
	ins := NewQueryInsert(
		InsertUnsharded,
		&vindexes.Keyspace{
			Name:    "ks",
			Sharded: false,
		},
		"dummy_insert",
	)
	ins.Generate = &Generate{
		Keyspace: &vindexes.Keyspace{
			Name:    "ks2",
			Sharded: false,
		},
		Query: "dummy_generate",
		Values: evalengine.NewTupleExpr(
			evalengine.NewLiteralInt(1),
			evalengine.NullExpr,
			evalengine.NewLiteralInt(2),
			evalengine.NullExpr,
			evalengine.NewLiteralInt(3),
		),
	}

	vc := newDMLTestVCursor("0")
	vc.results = []*sqltypes.Result{
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"nextval",
				"int64",
			),
			"4",
		),
		{InsertID: 1},
	}

	result, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		// Fetch two sequence value.
		`ResolveDestinations ks2 [] Destinations:DestinationAnyShard()`,
		`ExecuteStandalone dummy_generate n: type:INT64 value:"2" ks2 0`,
		// Fill those values into the insert.
		`ResolveDestinations ks [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard ks.0: dummy_insert {__seq0: type:INT64 value:"1" __seq1: type:INT64 value:"4" __seq2: type:INT64 value:"2" __seq3: type:INT64 value:"5" __seq4: type:INT64 value:"3"} true true`,
	})

	// The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues.
	expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 4})
}

func TestInsertUnshardedGenerate_Zeros(t *testing.T) {
	ins := NewQueryInsert(
		InsertUnsharded,
		&vindexes.Keyspace{
			Name:    "ks",
			Sharded: false,
		},
		"dummy_insert",
	)
	ins.Generate = &Generate{
		Keyspace: &vindexes.Keyspace{
			Name:    "ks2",
			Sharded: false,
		},
		Query: "dummy_generate",
		Values: evalengine.NewTupleExpr(
			evalengine.NewLiteralInt(1),
			evalengine.NewLiteralInt(0),
			evalengine.NewLiteralInt(2),
			evalengine.NewLiteralInt(0),
			evalengine.NewLiteralInt(3),
		),
	}

	vc := newDMLTestVCursor("0")
	vc.results = []*sqltypes.Result{
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"nextval",
				"int64",
			),
			"4",
		),
		{InsertID: 1},
	}

	result, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		// Fetch two sequence value.
		`ResolveDestinations ks2 [] Destinations:DestinationAnyShard()`,
		`ExecuteStandalone dummy_generate n: type:INT64 value:"2" ks2 0`,
		// Fill those values into the insert.
		`ResolveDestinations ks [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard ks.0: dummy_insert {__seq0: type:INT64 value:"1" __seq1: type:INT64 value:"4" __seq2: type:INT64 value:"2" __seq3: type:INT64 value:"5" __seq4: type:INT64 value:"3"} true true`,
	})

	// The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues.
	expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 4})
}

func TestInsertShardedSimple(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash",
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	// A single row insert should be autocommitted
	ins := NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				evalengine.NewLiteralInt(1),
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1"},
		" suffix",
	)
	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		// Based on shardForKsid, values returned will be 20-.
		`ResolveDestinations sharded [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`,
		// Row 2 will go to -20, rows 1 & 3 will go to 20-
		`ExecuteMultiShard ` +
			`sharded.20-: prefix mid1 suffix {_id_0: type:INT64 value:"1"} ` +
			`true true`,
	})

	// Multiple rows are not autocommitted by default
	ins = NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			// 3 rows.
			{
				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(2),
				evalengine.NewLiteralInt(3),
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)
	vc = newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}

	_, err = ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		// Based on shardForKsid, values returned will be 20-, -20, 20-.
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		// Row 2 will go to -20, rows 1 & 3 will go to 20-
		`ExecuteMultiShard ` +
			`sharded.20-: prefix mid1, mid3 suffix {_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`sharded.-20: prefix mid2 suffix {_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`true false`,
	})

	// Optional flag overrides autocommit
	ins = NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			// 3 rows.
			{
				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(2),
				evalengine.NewLiteralInt(3),
			},
		}},

		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)
	ins.MultiShardAutocommit = true

	vc = newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}

	_, err = ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		// Based on shardForKsid, values returned will be 20-, -20, 20-.
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		// Row 2 will go to -20, rows 1 & 3 will go to 20-
		`ExecuteMultiShard ` +
			`sharded.20-: prefix mid1, mid3 suffix {_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`sharded.-20: prefix mid2 suffix {_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`true true`,
	})
}

func TestInsertShardedFail(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"primary": {
						Type: "lookup_unique",
						Params: map[string]string{
							"table": "prim",
							"from":  "from1",
							"to":    "toc",
						},
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "primary",
							Columns: []string{"id"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				evalengine.NewLiteralInt(1),
			},
		}},

		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)

	vc := &loggingVCursor{}

	// The lookup will fail to map to a keyspace id.
	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.EqualError(t, err, `could not map [INT64(1)] to a keyspace id`)
}

func TestInsertShardedGenerate(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash",
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				// 3 rows.
				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(2),
				evalengine.NewLiteralInt(3),
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)

	ins.Generate = &Generate{
		Keyspace: &vindexes.Keyspace{
			Name:    "ks2",
			Sharded: false,
		},
		Query: "dummy_generate",
		Values: evalengine.NewTupleExpr(
			evalengine.NewLiteralInt(1),
			evalengine.NullExpr,
			evalengine.NewLiteralInt(2),
		),
	}

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}
	vc.results = []*sqltypes.Result{
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"nextval",
				"int64",
			),
			"2",
		),
		{InsertID: 1},
	}

	result, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		`ResolveDestinations ks2 [] Destinations:DestinationAnyShard()`,
		`ExecuteStandalone dummy_generate n: type:INT64 value:"1" ks2 -20`,
		// Based on shardForKsid, values returned will be 20-, -20, 20-.
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		// Row 2 will go to -20, rows 1 & 3 will go to 20-
		`ExecuteMultiShard ` +
			`sharded.20-: prefix mid1, mid3 suffix ` +
			`{__seq0: type:INT64 value:"1" __seq1: type:INT64 value:"2" __seq2: type:INT64 value:"2" ` +
			`_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`sharded.-20: prefix mid2 suffix ` +
			`{__seq0: type:INT64 value:"1" __seq1: type:INT64 value:"2" __seq2: type:INT64 value:"2" ` +
			`_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`true false`,
	})

	// The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues.
	expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 2})
}

func TestInsertShardedOwned(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash",
					},
					"twocol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp2",
							"from":  "from1,from2",
							"to":    "toc",
						},
						Owner: "t1",
					},
					"onecol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp1",
							"from":  "from",
							"to":    "toc",
						},
						Owner: "t1",
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"},
						}, {
							Name:    "twocol",
							Columns: []string{"c1", "c2"},
						}, {
							Name:    "onecol",
							Columns: []string{"c3"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				// rows for id
				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(2),
				evalengine.NewLiteralInt(3),
			},
		}, {
			// colVindex columns: c1, c2
			{
				evalengine.NewLiteralInt(4),
				evalengine.NewLiteralInt(5),
				evalengine.NewLiteralInt(6),
			},
			{
				evalengine.NewLiteralInt(7),
				evalengine.NewLiteralInt(8),
				evalengine.NewLiteralInt(9),
			},
		}, {
			// colVindex columns: c3
			{
				evalengine.NewLiteralInt(10),
				evalengine.NewLiteralInt(11),
				evalengine.NewLiteralInt(12),
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		`Execute insert into lkp2(from1, from2, toc) values(:from1_0, :from2_0, :toc_0), (:from1_1, :from2_1, :toc_1), (:from1_2, :from2_2, :toc_2) ` +
			`from1_0: type:INT64 value:"4" from1_1: type:INT64 value:"5" from1_2: type:INT64 value:"6" ` +
			`from2_0: type:INT64 value:"7" from2_1: type:INT64 value:"8" from2_2: type:INT64 value:"9" ` +
			`toc_0: type:VARBINARY value:"\x16k@\xb4J\xbaK\xd6" toc_1: type:VARBINARY value:"\x06\xe7\xea\"Βp\x8f" toc_2: type:VARBINARY value:"N\xb1\x90ɢ\xfa\x16\x9c" true`,
		`Execute insert into lkp1(from, toc) values(:from_0, :toc_0), (:from_1, :toc_1), (:from_2, :toc_2) ` +
			`from_0: type:INT64 value:"10" from_1: type:INT64 value:"11" from_2: type:INT64 value:"12" ` +
			`toc_0: type:VARBINARY value:"\x16k@\xb4J\xbaK\xd6" toc_1: type:VARBINARY value:"\x06\xe7\xea\"Βp\x8f" toc_2: type:VARBINARY value:"N\xb1\x90ɢ\xfa\x16\x9c" true`,
		// Based on shardForKsid, values returned will be 20-, -20, 20-.
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		`ExecuteMultiShard ` +
			`sharded.20-: prefix mid1, mid3 suffix ` +
			`{_c1_0: type:INT64 value:"4" _c1_1: type:INT64 value:"5" _c1_2: type:INT64 value:"6" ` +
			`_c2_0: type:INT64 value:"7" _c2_1: type:INT64 value:"8" _c2_2: type:INT64 value:"9" ` +
			`_c3_0: type:INT64 value:"10" _c3_1: type:INT64 value:"11" _c3_2: type:INT64 value:"12" ` +
			`_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`sharded.-20: prefix mid2 suffix ` +
			`{_c1_0: type:INT64 value:"4" _c1_1: type:INT64 value:"5" _c1_2: type:INT64 value:"6" ` +
			`_c2_0: type:INT64 value:"7" _c2_1: type:INT64 value:"8" _c2_2: type:INT64 value:"9" ` +
			`_c3_0: type:INT64 value:"10" _c3_1: type:INT64 value:"11" _c3_2: type:INT64 value:"12" ` +
			`_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`true false`,
	})
}

func TestInsertShardedOwnedWithNull(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash",
					},
					"onecol": {
						Type: "lookup",
						Params: map[string]string{
							"table":        "lkp1",
							"from":         "from",
							"to":           "toc",
							"ignore_nulls": "true",
						},
						Owner: "t1",
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"},
						}, {
							Name:    "onecol",
							Columns: []string{"c3"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				// rows for id
				evalengine.NewLiteralInt(1),
			},
		}, {
			// colVindex columns: c3
			{
				evalengine.NullExpr,
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`,
		`ExecuteMultiShard sharded.20-: prefix mid1 suffix ` +
			`{_c3_0:  _id_0: type:INT64 value:"1"} true true`,
	})
}

func TestInsertShardedGeo(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"geo": {
						Type: "region_experimental",
						Params: map[string]string{
							"region_bytes": "1",
						},
					},
					"lookup": {
						Type: "lookup_unique",
						Params: map[string]string{
							"table": "id_idx",
							"from":  "id",
							"to":    "keyspace_id",
						},
						Owner: "t1",
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "geo",
							Columns: []string{"region", "id"},
						}, {
							Name:    "lookup",
							Columns: []string{"id"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: region, id
			{
				// rows for region
				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(255),
			},
			{
				// rows for id
				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(1),
			},
		}, {
			// colVindex columns: id
			{
				// rows for id
				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(1),
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2"},
		" suffix",
	)
	for _, colVindex := range ks.Tables["t1"].ColumnVindexes {
		if colVindex.IsPartialVindex() {
			continue
		}
		ins.ColVindexes = append(ins.ColVindexes, colVindex)
	}

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20"}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		`Execute insert into id_idx(id, keyspace_id) values(:id_0, :keyspace_id_0), (:id_1, :keyspace_id_1) ` +
			`id_0: type:INT64 value:"1" id_1: type:INT64 value:"1" ` +
			`keyspace_id_0: type:VARBINARY value:"\x01\x16k@\xb4J\xbaK\xd6" keyspace_id_1: type:VARBINARY value:"\xff\x16k@\xb4J\xbaK\xd6" true`,
		`ResolveDestinations sharded [value:"0" value:"1"] Destinations:DestinationKeyspaceID(01166b40b44aba4bd6),DestinationKeyspaceID(ff166b40b44aba4bd6)`,
		`ExecuteMultiShard sharded.20-: prefix mid1 suffix ` +
			`{_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"1" ` +
			`_region_0: type:INT64 value:"1" _region_1: type:INT64 value:"255"} ` +
			`sharded.-20: prefix mid2 suffix ` +
			`{_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"1" ` +
			`_region_0: type:INT64 value:"1" _region_1: type:INT64 value:"255"} ` +
			`true false`,
	})
}

func TestInsertShardedIgnoreOwned(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"primary": {
						Type: "lookup_unique",
						Params: map[string]string{
							"table": "prim",
							"from":  "from1",
							"to":    "toc",
						},
					},
					"twocol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp2",
							"from":  "from1,from2",
							"to":    "toc",
						},
						Owner: "t1",
					},
					"onecol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp1",
							"from":  "from",
							"to":    "toc",
						},
						Owner: "t1",
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "primary",
							Columns: []string{"id"},
						}, {
							Name:    "twocol",
							Columns: []string{"c1", "c2"},
						}, {
							Name:    "onecol",
							Columns: []string{"c3"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		true,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				// rows for id

				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(2),
				evalengine.NewLiteralInt(3),
				evalengine.NewLiteralInt(4),
			},
		}, {
			// colVindex columns: c1, c2
			{
				// rows for c1
				evalengine.NewLiteralInt(5),
				evalengine.NewLiteralInt(6),
				evalengine.NewLiteralInt(7),
				evalengine.NewLiteralInt(8),
			},
			{
				// rows for c2
				evalengine.NewLiteralInt(9),
				evalengine.NewLiteralInt(10),
				evalengine.NewLiteralInt(11),
				evalengine.NewLiteralInt(12),
			},
		}, {
			// colVindex columns: c3
			{
				// rows for c3
				evalengine.NewLiteralInt(13),
				evalengine.NewLiteralInt(14),
				evalengine.NewLiteralInt(15),
				evalengine.NewLiteralInt(16),
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3", " mid4"},
		" suffix",
	)

	ksid0Lookup := sqltypes.MakeTestResult(
		sqltypes.MakeTestFields(
			"from|to",
			"int64|varbinary",
		),
		"1|\x00",
		"3|\x00",
		"4|\x00",
	)
	ksid0 := sqltypes.MakeTestResult(
		sqltypes.MakeTestFields(
			"to",
			"varbinary",
		),
		"\x00",
	)
	noresult := &sqltypes.Result{}
	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20"}
	vc.results = []*sqltypes.Result{
		// primary vindex lookups: fail row 2.
		ksid0Lookup,
		// insert lkp2
		noresult,
		// fail one verification (row 3)
		ksid0,
		noresult,
		ksid0,
		// insert lkp1
		noresult,
		// verify lkp1 (only two rows to verify)
		ksid0,
		ksid0,
	}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		`Execute select from1, toc from prim where from1 in ::from1 from1: type:TUPLE values:{type:INT64 value:"1"} values:{type:INT64 value:"2"} values:{type:INT64 value:"3"} values:{type:INT64 value:"4"} false`,
		`Execute insert ignore into lkp2(from1, from2, toc) values(:from1_0, :from2_0, :toc_0), (:from1_1, :from2_1, :toc_1), (:from1_2, :from2_2, :toc_2) ` +
			`from1_0: type:INT64 value:"5" from1_1: type:INT64 value:"7" from1_2: type:INT64 value:"8" ` +
			`from2_0: type:INT64 value:"9" from2_1: type:INT64 value:"11" from2_2: type:INT64 value:"12" ` +
			`toc_0: type:VARBINARY value:"\x00" toc_1: type:VARBINARY value:"\x00" toc_2: type:VARBINARY value:"\x00" ` +
			`true`,
		// row 2 is out because it didn't map to a ksid.
		`Execute select from1 from lkp2 where from1 = :from1 and toc = :toc from1: type:INT64 value:"5" toc: type:VARBINARY value:"\x00" false`,
		`Execute select from1 from lkp2 where from1 = :from1 and toc = :toc from1: type:INT64 value:"7" toc: type:VARBINARY value:"\x00" false`,
		`Execute select from1 from lkp2 where from1 = :from1 and toc = :toc from1: type:INT64 value:"8" toc: type:VARBINARY value:"\x00" false`,
		`Execute insert ignore into lkp1(from, toc) values(:from_0, :toc_0), (:from_1, :toc_1) ` +
			`from_0: type:INT64 value:"13" from_1: type:INT64 value:"16" ` +
			`toc_0: type:VARBINARY value:"\x00" toc_1: type:VARBINARY value:"\x00" ` +
			`true`,
		// row 3 is out because it failed Verify. Only two verifications from lkp1.
		`Execute select from from lkp1 where from = :from and toc = :toc from: type:INT64 value:"13" toc: type:VARBINARY value:"\x00" false`,
		`Execute select from from lkp1 where from = :from and toc = :toc from: type:INT64 value:"16" toc: type:VARBINARY value:"\x00" false`,
		`ResolveDestinations sharded [value:"0" value:"3"] Destinations:DestinationKeyspaceID(00),DestinationKeyspaceID(00)`,
		// Bind vars for rows 2 & 3 may be missing because they were not sent.
		`ExecuteMultiShard ` +
			`sharded.20-: prefix mid1 suffix ` +
			`{_c1_0: type:INT64 value:"5" _c1_3: type:INT64 value:"8" ` +
			`_c2_0: type:INT64 value:"9" _c2_3: type:INT64 value:"12" ` +
			`_c3_0: type:INT64 value:"13" _c3_3: type:INT64 value:"16" ` +
			`_id_0: type:INT64 value:"1" _id_3: type:INT64 value:"4"} ` +
			`sharded.-20: prefix mid4 suffix ` +
			`{_c1_0: type:INT64 value:"5" _c1_3: type:INT64 value:"8" ` +
			`_c2_0: type:INT64 value:"9" _c2_3: type:INT64 value:"12" ` +
			`_c3_0: type:INT64 value:"13" _c3_3: type:INT64 value:"16" ` +
			`_id_0: type:INT64 value:"1" _id_3: type:INT64 value:"4"} ` +
			`true false`,
	})
}

func TestInsertShardedIgnoreOwnedWithNull(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"primary": {
						Type: "hash",
					},
					"onecol": {
						Type: "lookup",
						Params: map[string]string{
							"table":        "lkp1",
							"from":         "from",
							"to":           "toc",
							"ignore_nulls": "true",
						},
						Owner: "t1",
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "primary",
							Columns: []string{"id"},
						}, {
							Name:    "onecol",
							Columns: []string{"c3"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		true,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				// rows for id
				evalengine.NewLiteralInt(1),
			},
		}, {
			// colVindex columns: c3
			{
				// rows for c3
				evalengine.NullExpr,
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3", " mid4"},
		" suffix",
	)

	ksid0 := sqltypes.MakeTestResult(
		sqltypes.MakeTestFields(
			"to",
			"varbinary",
		),
		"\x00",
	)
	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"-20", "20-"}
	vc.results = []*sqltypes.Result{
		ksid0,
		ksid0,
		ksid0,
	}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		`Execute select from from lkp1 where from = :from and toc = :toc from:  toc: type:VARBINARY value:"\x16k@\xb4J\xbaK\xd6" false`,
		`ResolveDestinations sharded [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`,
		`ExecuteMultiShard sharded.-20: prefix mid1 suffix ` +
			`{_c3_0:  _id_0: type:INT64 value:"1"} true true`,
	})
}

func TestInsertShardedUnownedVerify(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash",
					},
					"twocol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp2",
							"from":  "from1,from2",
							"to":    "toc",
						},
					},
					"onecol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp1",
							"from":  "from",
							"to":    "toc",
						},
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"},
						}, {
							Name:    "twocol",
							Columns: []string{"c1", "c2"},
						}, {
							Name:    "onecol",
							Columns: []string{"c3"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				// rows for id
				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(2),
				evalengine.NewLiteralInt(3),
			},
		}, {
			// colVindex columns: c1, c2
			{
				// rows for c1
				evalengine.NewLiteralInt(4),
				evalengine.NewLiteralInt(5),
				evalengine.NewLiteralInt(6),
			},
			{
				// rows for c2
				evalengine.NewLiteralInt(7),
				evalengine.NewLiteralInt(8),
				evalengine.NewLiteralInt(9),
			},
		}, {
			// colVindex columns: c3
			{
				// rows for c3
				evalengine.NewLiteralInt(10),
				evalengine.NewLiteralInt(11),
				evalengine.NewLiteralInt(12),
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)

	// nonemptyResult will cause the lookup verify queries to succeed.
	nonemptyResult := sqltypes.MakeTestResult(
		sqltypes.MakeTestFields(
			"c1",
			"int64",
		),
		"1",
	)

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}
	vc.results = []*sqltypes.Result{
		nonemptyResult,
		nonemptyResult,
		nonemptyResult,
		nonemptyResult,
		nonemptyResult,
		nonemptyResult,
	}
	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		// Perform verification for each colvindex.
		// Note that only first column of each colvindex is used.
		`Execute select from1 from lkp2 where from1 = :from1 and toc = :toc from1: type:INT64 value:"4" toc: type:VARBINARY value:"\x16k@\xb4J\xbaK\xd6" false`,
		`Execute select from1 from lkp2 where from1 = :from1 and toc = :toc from1: type:INT64 value:"5" toc: type:VARBINARY value:"\x06\xe7\xea\"Βp\x8f" false`,
		`Execute select from1 from lkp2 where from1 = :from1 and toc = :toc from1: type:INT64 value:"6" toc: type:VARBINARY value:"N\xb1\x90ɢ\xfa\x16\x9c" false`,
		`Execute select from from lkp1 where from = :from and toc = :toc from: type:INT64 value:"10" toc: type:VARBINARY value:"\x16k@\xb4J\xbaK\xd6" false`,
		`Execute select from from lkp1 where from = :from and toc = :toc from: type:INT64 value:"11" toc: type:VARBINARY value:"\x06\xe7\xea\"Βp\x8f" false`,
		`Execute select from from lkp1 where from = :from and toc = :toc from: type:INT64 value:"12" toc: type:VARBINARY value:"N\xb1\x90ɢ\xfa\x16\x9c" false`,
		// Based on shardForKsid, values returned will be 20-, -20, 20-.
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		`ExecuteMultiShard ` +
			`sharded.20-: prefix mid1, mid3 suffix ` +
			`{_c1_0: type:INT64 value:"4" _c1_1: type:INT64 value:"5" _c1_2: type:INT64 value:"6" ` +
			`_c2_0: type:INT64 value:"7" _c2_1: type:INT64 value:"8" _c2_2: type:INT64 value:"9" ` +
			`_c3_0: type:INT64 value:"10" _c3_1: type:INT64 value:"11" _c3_2: type:INT64 value:"12" ` +
			`_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`sharded.-20: prefix mid2 suffix ` +
			`{_c1_0: type:INT64 value:"4" _c1_1: type:INT64 value:"5" _c1_2: type:INT64 value:"6" ` +
			`_c2_0: type:INT64 value:"7" _c2_1: type:INT64 value:"8" _c2_2: type:INT64 value:"9" ` +
			`_c3_0: type:INT64 value:"10" _c3_1: type:INT64 value:"11" _c3_2: type:INT64 value:"12" ` +
			`_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`true false`,
	})
}

func TestInsertShardedIgnoreUnownedVerify(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash",
					},
					"onecol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp1",
							"from":  "from",
							"to":    "toc",
						},
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"},
						}, {
							Name:    "onecol",
							Columns: []string{"c3"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		true,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				// rows for id
				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(2),
				evalengine.NewLiteralInt(3),
			},
		}, {
			// colVindex columns: c3
			{
				// rows for c3
				evalengine.NewLiteralInt(10),
				evalengine.NewLiteralInt(11),
				evalengine.NewLiteralInt(12),
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)

	// nonemptyResult will cause the lookup verify queries to succeed.
	nonemptyResult := sqltypes.MakeTestResult(
		sqltypes.MakeTestFields(
			"c1",
			"int64",
		),
		"1",
	)

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20"}
	vc.results = []*sqltypes.Result{
		nonemptyResult,
		// fail verification of second row.
		{},
		nonemptyResult,
	}
	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		// Perform verification for each colvindex.
		// Note that only first column of each colvindex is used.
		`Execute select from from lkp1 where from = :from and toc = :toc from: type:INT64 value:"10" toc: type:VARBINARY value:"\x16k@\xb4J\xbaK\xd6" false`,
		`Execute select from from lkp1 where from = :from and toc = :toc from: type:INT64 value:"11" toc: type:VARBINARY value:"\x06\xe7\xea\"Βp\x8f" false`,
		`Execute select from from lkp1 where from = :from and toc = :toc from: type:INT64 value:"12" toc: type:VARBINARY value:"N\xb1\x90ɢ\xfa\x16\x9c" false`,
		// Based on shardForKsid, values returned will be 20-, -20.
		`ResolveDestinations sharded [value:"0" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		`ExecuteMultiShard ` +
			`sharded.20-: prefix mid1 suffix ` +
			`{_c3_0: type:INT64 value:"10" _c3_2: type:INT64 value:"12" ` +
			`_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` +
			`sharded.-20: prefix mid3 suffix ` +
			`{_c3_0: type:INT64 value:"10" _c3_2: type:INT64 value:"12" ` +
			`_id_0: type:INT64 value:"1" _id_2: type:INT64 value:"3"} ` +
			`true false`,
	})
}

func TestInsertShardedIgnoreUnownedVerifyFail(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash",
					},
					"onecol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp1",
							"from":  "from",
							"to":    "toc",
						},
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"},
						}, {
							Name:    "onecol",
							Columns: []string{"c3"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				// rows for id
				evalengine.NewLiteralInt(1),
			},
		}, {
			// colVindex columns: c3
			{
				// rows for c3
				evalengine.NewLiteralInt(2),
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)

	vc := newDMLTestVCursor("-20", "20-")

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.EqualError(t, err, `values [[INT64(2)]] for column [c3] does not map to keyspace ids`)
}

func TestInsertShardedUnownedReverseMap(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash",
					},
					"twocol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp2",
							"from":  "from1,from2",
							"to":    "toc",
						},
					},
					"onecol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp1",
							"from":  "from",
							"to":    "toc",
						},
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"},
						}, {
							Name:    "hash",
							Columns: []string{"c1", "c2"},
						}, {
							Name:    "hash",
							Columns: []string{"c3"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				// rows for id
				evalengine.NewLiteralInt(1),
				evalengine.NewLiteralInt(2),
				evalengine.NewLiteralInt(3),
			},
		}, {
			// colVindex columns: c1, c2
			{
				// rows for c1
				evalengine.NullExpr,
				evalengine.NullExpr,
				evalengine.NullExpr,
			},
			{
				// rows for c2
				evalengine.NullExpr,
				evalengine.NullExpr,
				evalengine.NullExpr,
			},
		}, {
			// colVindex columns: c3
			{
				// rows for c3
				evalengine.NullExpr,
				evalengine.NullExpr,
				evalengine.NullExpr,
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)

	// nonemptyResult will cause the lookup verify queries to succeed.
	nonemptyResult := sqltypes.MakeTestResult(
		sqltypes.MakeTestFields(
			"c1",
			"int64",
		),
		"1",
	)

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}
	vc.results = []*sqltypes.Result{
		nonemptyResult,
	}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	if err != nil {
		t.Fatal(err)
	}
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		`ExecuteMultiShard ` +
			`sharded.20-: prefix mid1, mid3 suffix ` +
			`{_c1_0: type:UINT64 value:"1" _c1_1: type:UINT64 value:"2" _c1_2: type:UINT64 value:"3" ` +
			`_c2_0:  _c2_1:  _c2_2:  ` +
			`_c3_0: type:UINT64 value:"1" _c3_1: type:UINT64 value:"2" _c3_2: type:UINT64 value:"3" ` +
			`_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`sharded.-20: prefix mid2 suffix ` +
			`{_c1_0: type:UINT64 value:"1" _c1_1: type:UINT64 value:"2" _c1_2: type:UINT64 value:"3" ` +
			`_c2_0:  _c2_1:  _c2_2:  ` +
			`_c3_0: type:UINT64 value:"1" _c3_1: type:UINT64 value:"2" _c3_2: type:UINT64 value:"3" ` +
			`_id_0: type:INT64 value:"1" _id_1: type:INT64 value:"2" _id_2: type:INT64 value:"3"} ` +
			`true false`,
	})
}

func TestInsertShardedUnownedReverseMapSuccess(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash",
					},
					"onecol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp1",
							"from":  "from",
							"to":    "toc",
						},
					},
				},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"},
						}, {
							Name:    "onecol",
							Columns: []string{"c3"},
						}},
					},
				},
			},
		},
	}
	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := NewInsert(
		InsertSharded,
		false,
		ks.Keyspace,
		[][][]evalengine.Expr{{
			// colVindex columns: id
			{
				// rows for id
				evalengine.NewLiteralInt(1),
			},
		}, {
			// colVindex columns: c3
			{
				// rows for c3
				evalengine.NullExpr,
			},
		}},
		ks.Tables["t1"],
		"prefix",
		[]string{" mid1", " mid2", " mid3"},
		" suffix",
	)

	vc := newDMLTestVCursor("-20", "20-")

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.NoError(t, err)
}

func TestInsertSelectSimple(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {Type: "hash"}},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"}}}}}}}}

	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	// A single row insert should be autocommitted
	ins := &Insert{
		Opcode:            InsertSelect,
		Keyspace:          ks.Keyspace,
		Query:             "dummy_insert",
		Table:             ks.Tables["t1"],
		VindexValueOffset: [][]int{{1}},
		Input: &Route{
			Query:      "dummy_select",
			FieldQuery: "dummy_field_query",
			RoutingParameters: &RoutingParameters{
				Opcode:   Scatter,
				Keyspace: ks.Keyspace}}}

	ins.ColVindexes = append(ins.ColVindexes, ks.Tables["t1"].ColumnVindexes...)
	ins.Prefix = "prefix "
	ins.Suffix = " suffix"

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}
	vc.results = []*sqltypes.Result{
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"name|id",
				"varchar|int64"),
			"a|1",
			"a|3",
			"b|2")}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [] Destinations:DestinationAllShards()`,

		// the select query
		`ExecuteMultiShard sharded.-20: dummy_select {} sharded.20-: dummy_select {} false false`,
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(4eb190c9a2fa169c),DestinationKeyspaceID(06e7ea22ce92708f)`,

		// two rows go to the 20- shard, and one row go to the -20 shard
		`ExecuteMultiShard ` +
			`sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` +
			`{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1"` +
			` _c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"2"} ` +
			`sharded.-20: prefix values (:_c1_0, :_c1_1) suffix` +
			` {_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"3"} true false`})

	vc.Rewind()
	err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error {
		return nil
	})
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [] Destinations:DestinationAllShards()`,

		// the select query
		`StreamExecuteMulti dummy_select sharded.-20: {} sharded.20-: {} `,
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(4eb190c9a2fa169c),DestinationKeyspaceID(06e7ea22ce92708f)`,

		// two rows go to the 20- shard, and one row go to the -20 shard
		`ExecuteMultiShard ` +
			`sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` +
			`{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1"` +
			` _c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"2"} ` +
			`sharded.-20: prefix values (:_c1_0, :_c1_1) suffix` +
			` {_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"3"} true false`})
}

func TestInsertSelectOwned(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {Type: "hash"},
					"onecol": {
						Type: "lookup",
						Params: map[string]string{
							"table": "lkp1",
							"from":  "from",
							"to":    "toc"},
						Owner: "t1"}},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"}}, {
							Name:    "onecol",
							Columns: []string{"c3"}}}}}}}}

	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := &Insert{
		Opcode:   InsertSelect,
		Keyspace: ks.Keyspace,
		Query:    "dummy_insert",
		Table:    ks.Tables["t1"],
		VindexValueOffset: [][]int{
			{1},  // The primary vindex has a single column as sharding key
			{0}}, // the onecol vindex uses the 'name' column
		Input: &Route{
			Query:      "dummy_select",
			FieldQuery: "dummy_field_query",
			RoutingParameters: &RoutingParameters{
				Opcode:   Scatter,
				Keyspace: ks.Keyspace}}}

	ins.ColVindexes = append(ins.ColVindexes, ks.Tables["t1"].ColumnVindexes...)
	ins.Prefix = "prefix "
	ins.Suffix = " suffix"

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}
	vc.results = []*sqltypes.Result{
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"name|id",
				"varchar|int64"),
			"a|1",
			"a|3",
			"b|2")}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [] Destinations:DestinationAllShards()`,

		// the select query
		`ExecuteMultiShard sharded.-20: dummy_select {} sharded.20-: dummy_select {} false false`,

		// insert values into the owned lookup vindex
		`Execute insert into lkp1(from, toc) values(:from_0, :toc_0), (:from_1, :toc_1), (:from_2, :toc_2) from_0: type:VARCHAR value:"a" from_1: type:VARCHAR value:"a" from_2: type:VARCHAR value:"b" toc_0: type:VARBINARY value:"\x16k@\xb4J\xbaK\xd6" toc_1: type:VARBINARY value:"N\xb1\x90ɢ\xfa\x16\x9c" toc_2: type:VARBINARY value:"\x06\xe7\xea\"Βp\x8f" true`,

		// Values 0 1 2 come from the id column
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(4eb190c9a2fa169c),DestinationKeyspaceID(06e7ea22ce92708f)`,

		// insert values into the main table
		`ExecuteMultiShard ` +
			// first we insert two rows on the 20- shard
			`sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` +
			`{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1" _c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"2"} ` +

			// next we insert one row on the -20 shard
			`sharded.-20: prefix values (:_c1_0, :_c1_1) suffix ` +
			`{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"3"} ` +
			`true false`})

	vc.Rewind()
	err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error {
		return nil
	})
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [] Destinations:DestinationAllShards()`,

		// the select query
		`StreamExecuteMulti dummy_select sharded.-20: {} sharded.20-: {} `,

		// insert values into the owned lookup vindex
		`Execute insert into lkp1(from, toc) values(:from_0, :toc_0), (:from_1, :toc_1), (:from_2, :toc_2) from_0: type:VARCHAR value:"a" from_1: type:VARCHAR value:"a" from_2: type:VARCHAR value:"b" toc_0: type:VARBINARY value:"\x16k@\xb4J\xbaK\xd6" toc_1: type:VARBINARY value:"N\xb1\x90ɢ\xfa\x16\x9c" toc_2: type:VARBINARY value:"\x06\xe7\xea\"Βp\x8f" true`,

		// Values 0 1 2 come from the id column
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(4eb190c9a2fa169c),DestinationKeyspaceID(06e7ea22ce92708f)`,

		// insert values into the main table
		`ExecuteMultiShard ` +
			// first we insert two rows on the 20- shard
			`sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` +
			`{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1" _c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"2"} ` +

			// next we insert one row on the -20 shard
			`sharded.-20: prefix values (:_c1_0, :_c1_1) suffix ` +
			`{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"3"} ` +
			`true false`})
}

func TestInsertSelectGenerate(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash"}},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"}}}}}}}}

	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := &Insert{
		Opcode:   InsertSelect,
		Keyspace: ks.Keyspace,
		Query:    "dummy_insert",
		Table:    ks.Tables["t1"],
		VindexValueOffset: [][]int{
			{1}}, // The primary vindex has a single column as sharding key
		Input: &Route{
			Query:      "dummy_select",
			FieldQuery: "dummy_field_query",
			RoutingParameters: &RoutingParameters{
				Opcode:   Scatter,
				Keyspace: ks.Keyspace}}}

	ins.Generate = &Generate{
		Keyspace: &vindexes.Keyspace{
			Name:    "ks2",
			Sharded: false,
		},
		Query:  "dummy_generate",
		Offset: 1,
	}
	ins.Prefix = "prefix "
	ins.Suffix = " suffix"

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}
	vc.results = []*sqltypes.Result{
		// This is the result from the input SELECT
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"name|id",
				"varchar|int64"),
			"a|1",
			"a|null",
			"b|null"),
		// This is the result for the sequence query
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"nextval",
				"int64",
			),
			"2",
		),
		{InsertID: 1},
	}

	result, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [] Destinations:DestinationAllShards()`,
		// this is the input query
		`ExecuteMultiShard sharded.-20: dummy_select {} sharded.20-: dummy_select {} false false`,
		`ResolveDestinations ks2 [] Destinations:DestinationAnyShard()`,

		// this is the sequence table query
		`ExecuteStandalone dummy_generate n: type:INT64 value:"2" ks2 -20`,
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		`ExecuteMultiShard ` +
			// first we send the insert to the 20- shard
			`sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` +
			`{_c0_0: type:VARCHAR value:"a" ` +
			`_c0_1: type:INT64 value:"1" ` +
			`_c2_0: type:VARCHAR value:"b" ` +
			`_c2_1: type:INT64 value:"3"} ` +
			// next we send the insert to the -20 shard
			`sharded.-20: prefix values (:_c1_0, :_c1_1) suffix ` +
			`{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"2"} ` +
			`true false`,
	})

	// The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues.
	expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 2})
}

func TestStreamingInsertSelectGenerate(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash"}},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"}}}}}}}}

	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := &Insert{
		Opcode:   InsertSelect,
		Keyspace: ks.Keyspace,
		Query:    "dummy_insert",
		Table:    ks.Tables["t1"],
		VindexValueOffset: [][]int{
			{1}}, // The primary vindex has a single column as sharding key
		Input: &Route{
			Query:      "dummy_select",
			FieldQuery: "dummy_field_query",
			RoutingParameters: &RoutingParameters{
				Opcode:   Scatter,
				Keyspace: ks.Keyspace}}}

	ins.Generate = &Generate{
		Keyspace: &vindexes.Keyspace{
			Name:    "ks2",
			Sharded: false,
		},
		Query:  "dummy_generate",
		Offset: 1,
	}
	ins.Prefix = "prefix "
	ins.Suffix = " suffix"

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}
	vc.results = []*sqltypes.Result{
		// This is the result from the input SELECT
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"name|id",
				"varchar|int64"),
			"a|1",
			"a|null",
			"b|null"),
		// This is the result for the sequence query
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"nextval",
				"int64",
			),
			"2",
		),
		{InsertID: 1},
	}

	var output *sqltypes.Result
	err := ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error {
		output = result
		return nil
	})
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [] Destinations:DestinationAllShards()`,
		// this is the input query
		`StreamExecuteMulti dummy_select sharded.-20: {} sharded.20-: {} `,
		`ResolveDestinations ks2 [] Destinations:DestinationAnyShard()`,

		// this is the sequence table query
		`ExecuteStandalone dummy_generate n: type:INT64 value:"2" ks2 -20`,
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		`ExecuteMultiShard ` +
			// first we send the insert to the 20- shard
			`sharded.20-: prefix values (:_c0_0, :_c0_1), (:_c2_0, :_c2_1) suffix ` +
			`{_c0_0: type:VARCHAR value:"a" ` +
			`_c0_1: type:INT64 value:"1" ` +
			`_c2_0: type:VARCHAR value:"b" ` +
			`_c2_1: type:INT64 value:"3"} ` +
			// next we send the insert to the -20 shard
			`sharded.-20: prefix values (:_c1_0, :_c1_1) suffix ` +
			`{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"2"} ` +
			`true false`,
	})

	// The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues.
	expectResult(t, "Execute", output, &sqltypes.Result{InsertID: 2})
}

func TestInsertSelectGenerateNotProvided(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash"}},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"}}}}}}}}

	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := &Insert{
		Opcode:   InsertSelect,
		Keyspace: ks.Keyspace,
		Query:    "dummy_insert",
		Table:    ks.Tables["t1"],
		VindexValueOffset: [][]int{
			{1}}, // The primary vindex has a single column as sharding key
		Input: &Route{
			Query:      "dummy_select",
			FieldQuery: "dummy_field_query",
			RoutingParameters: &RoutingParameters{
				Opcode:   Scatter,
				Keyspace: ks.Keyspace}}}

	ins.Generate = &Generate{
		Keyspace: &vindexes.Keyspace{
			Name:    "ks2",
			Sharded: false,
		},
		Query:  "dummy_generate",
		Offset: 2,
	}
	ins.Prefix = "prefix "
	ins.Suffix = " suffix"

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}
	vc.results = []*sqltypes.Result{
		// This is the result from the input SELECT
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"name|id",
				"varchar|int64"),
			"a|1",
			"a|2",
			"b|3"),
		// This is the result for the sequence query
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"nextval",
				"int64",
			),
			"10",
		),
		{InsertID: 1},
	}

	result, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [] Destinations:DestinationAllShards()`,
		// this is the input query
		`ExecuteMultiShard sharded.-20: dummy_select {} sharded.20-: dummy_select {} false false`,
		`ResolveDestinations ks2 [] Destinations:DestinationAnyShard()`,

		// this is the sequence table query
		`ExecuteStandalone dummy_generate n: type:INT64 value:"3" ks2 -20`,
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		`ExecuteMultiShard ` +
			`sharded.20-: prefix values (:_c0_0, :_c0_1, :_c0_2), (:_c2_0, :_c2_1, :_c2_2) suffix ` +
			`{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1" _c0_2: type:INT64 value:"10" ` +
			`_c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"3" _c2_2: type:INT64 value:"12"} ` +
			`sharded.-20: prefix values (:_c1_0, :_c1_1, :_c1_2) suffix ` +
			`{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"2" _c1_2: type:INT64 value:"11"} ` +
			`true false`,
	})

	// The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues.
	expectResult(t, "Execute", result, &sqltypes.Result{InsertID: 10})
}

func TestStreamingInsertSelectGenerateNotProvided(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {
						Type: "hash"}},
				Tables: map[string]*vschemapb.Table{
					"t1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"}}}}}}}}

	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := &Insert{
		Opcode:   InsertSelect,
		Keyspace: ks.Keyspace,
		Query:    "dummy_insert",
		Table:    ks.Tables["t1"],
		VindexValueOffset: [][]int{
			{1}}, // The primary vindex has a single column as sharding key
		Input: &Route{
			Query:      "dummy_select",
			FieldQuery: "dummy_field_query",
			RoutingParameters: &RoutingParameters{
				Opcode:   Scatter,
				Keyspace: ks.Keyspace}}}

	ins.Generate = &Generate{
		Keyspace: &vindexes.Keyspace{
			Name:    "ks2",
			Sharded: false,
		},
		Query:  "dummy_generate",
		Offset: 2,
	}
	ins.Prefix = "prefix "
	ins.Suffix = " suffix"

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}
	vc.results = []*sqltypes.Result{
		// This is the result from the input SELECT
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"name|id",
				"varchar|int64"),
			"a|1",
			"a|2",
			"b|3"),
		// This is the result for the sequence query
		sqltypes.MakeTestResult(
			sqltypes.MakeTestFields(
				"nextval",
				"int64",
			),
			"10",
		),
		{InsertID: 1},
	}

	var output *sqltypes.Result
	err := ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error {
		output = result
		return nil
	})
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [] Destinations:DestinationAllShards()`,
		// this is the input query
		`StreamExecuteMulti dummy_select sharded.-20: {} sharded.20-: {} `,
		`ResolveDestinations ks2 [] Destinations:DestinationAnyShard()`,

		// this is the sequence table query
		`ExecuteStandalone dummy_generate n: type:INT64 value:"3" ks2 -20`,
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6),DestinationKeyspaceID(06e7ea22ce92708f),DestinationKeyspaceID(4eb190c9a2fa169c)`,
		`ExecuteMultiShard ` +
			`sharded.20-: prefix values (:_c0_0, :_c0_1, :_c0_2), (:_c2_0, :_c2_1, :_c2_2) suffix ` +
			`{_c0_0: type:VARCHAR value:"a" _c0_1: type:INT64 value:"1" _c0_2: type:INT64 value:"10" ` +
			`_c2_0: type:VARCHAR value:"b" _c2_1: type:INT64 value:"3" _c2_2: type:INT64 value:"12"} ` +
			`sharded.-20: prefix values (:_c1_0, :_c1_1, :_c1_2) suffix ` +
			`{_c1_0: type:VARCHAR value:"a" _c1_1: type:INT64 value:"2" _c1_2: type:INT64 value:"11"} ` +
			`true false`,
	})

	// The insert id returned by ExecuteMultiShard should be overwritten by processGenerateFromValues.
	expectResult(t, "Execute", output, &sqltypes.Result{InsertID: 10})
}

func TestInsertSelectUnowned(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sharded": {
				Sharded: true,
				Vindexes: map[string]*vschemapb.Vindex{
					"hash": {Type: "hash"},
					"onecol": {
						Type: "lookup_unique",
						Params: map[string]string{
							"table": "lkp1",
							"from":  "from",
							"to":    "toc"},
						Owner: "t1"}},
				Tables: map[string]*vschemapb.Table{
					"t2": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "onecol",
							Columns: []string{"id"}}}}}}}}

	vs := vindexes.BuildVSchema(invschema)
	ks := vs.Keyspaces["sharded"]

	ins := &Insert{
		Opcode:   InsertSelect,
		Keyspace: ks.Keyspace,
		Query:    "dummy_insert",
		Table:    ks.Tables["t2"],
		VindexValueOffset: [][]int{
			{0}}, // the onecol vindex as unowned lookup sharding column
		Input: &Route{
			Query:      "dummy_select",
			FieldQuery: "dummy_field_query",
			RoutingParameters: &RoutingParameters{
				Opcode:   Scatter,
				Keyspace: ks.Keyspace}}}

	ins.ColVindexes = append(ins.ColVindexes, ks.Tables["t2"].ColumnVindexes...)
	ins.Prefix = "prefix "
	ins.Suffix = " suffix"

	vc := newDMLTestVCursor("-20", "20-")
	vc.shardForKsid = []string{"20-", "-20", "20-"}
	vc.results = []*sqltypes.Result{
		sqltypes.MakeTestResult(sqltypes.MakeTestFields("id", "int64"), "1", "3", "2"),
		sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|tocol", "int64|int64"), "1|1", "3|2", "2|3"),
	}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.NoError(t, err)

	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [] Destinations:DestinationAllShards()`,

		// the select query
		`ExecuteMultiShard sharded.-20: dummy_select {} sharded.20-: dummy_select {} false false`,

		// select values into the unowned lookup vindex for routing
		`Execute select from, toc from lkp1 where from in ::from from: type:TUPLE values:{type:INT64 value:"1"} values:{type:INT64 value:"3"} values:{type:INT64 value:"2"} false`,

		// values from lookup vindex resolved to destination
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(31),DestinationKeyspaceID(32),DestinationKeyspaceID(33)`,

		// insert values into the main table
		`ExecuteMultiShard ` +
			// first we insert two rows on the 20- shard
			`sharded.20-: prefix values (:_c0_0), (:_c2_0) suffix ` +
			`{_c0_0: type:INT64 value:"1" _c2_0: type:INT64 value:"2"} ` +

			// next we insert one row on the -20 shard
			`sharded.-20: prefix values (:_c1_0) suffix ` +
			`{_c1_0: type:INT64 value:"3"} ` +
			`true false`})

	vc.Rewind()
	err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error {
		return nil
	})
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		`ResolveDestinations sharded [] Destinations:DestinationAllShards()`,

		// the select query
		`StreamExecuteMulti dummy_select sharded.-20: {} sharded.20-: {} `,

		// select values into the unowned lookup vindex for routing
		`Execute select from, toc from lkp1 where from in ::from from: type:TUPLE values:{type:INT64 value:"1"} values:{type:INT64 value:"3"} values:{type:INT64 value:"2"} false`,

		// values from lookup vindex resolved to destination
		`ResolveDestinations sharded [value:"0" value:"1" value:"2"] Destinations:DestinationKeyspaceID(31),DestinationKeyspaceID(32),DestinationKeyspaceID(33)`,

		// insert values into the main table
		`ExecuteMultiShard ` +
			// first we insert two rows on the 20- shard
			`sharded.20-: prefix values (:_c0_0), (:_c2_0) suffix ` +
			`{_c0_0: type:INT64 value:"1" _c2_0: type:INT64 value:"2"} ` +

			// next we insert one row on the -20 shard
			`sharded.-20: prefix values (:_c1_0) suffix ` +
			`{_c1_0: type:INT64 value:"3"} ` +
			`true false`})
}

func TestInsertSelectShardingCases(t *testing.T) {
	invschema := &vschemapb.SrvVSchema{
		Keyspaces: map[string]*vschemapb.Keyspace{
			"sks1": {
				Sharded:  true,
				Vindexes: map[string]*vschemapb.Vindex{"hash": {Type: "hash"}},
				Tables: map[string]*vschemapb.Table{
					"s1": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"}}}}}},
			"sks2": {
				Sharded:  true,
				Vindexes: map[string]*vschemapb.Vindex{"hash": {Type: "hash"}},
				Tables: map[string]*vschemapb.Table{
					"s2": {
						ColumnVindexes: []*vschemapb.ColumnVindex{{
							Name:    "hash",
							Columns: []string{"id"}}}}}},
			"uks1": {Tables: map[string]*vschemapb.Table{"u1": {}}},
			"uks2": {Tables: map[string]*vschemapb.Table{"u2": {}}},
		}}

	vs := vindexes.BuildVSchema(invschema)
	sks1 := vs.Keyspaces["sks1"]
	sks2 := vs.Keyspaces["sks2"]
	uks1 := vs.Keyspaces["uks1"]
	uks2 := vs.Keyspaces["uks2"]

	// sharded input route.
	sRoute := &Route{
		Query:             "dummy_select",
		FieldQuery:        "dummy_field_query",
		RoutingParameters: &RoutingParameters{Opcode: Scatter, Keyspace: sks2.Keyspace}}

	// unsharded input route.
	uRoute := &Route{
		Query:             "dummy_select",
		FieldQuery:        "dummy_field_query",
		RoutingParameters: &RoutingParameters{Opcode: Unsharded, Keyspace: uks2.Keyspace}}

	// sks1 and sks2
	ins := &Insert{
		Opcode:            InsertSelect,
		Keyspace:          sks1.Keyspace,
		Query:             "dummy_insert",
		Table:             sks1.Tables["s1"],
		Prefix:            "prefix ",
		Suffix:            " suffix",
		ColVindexes:       sks1.Tables["s1"].ColumnVindexes,
		VindexValueOffset: [][]int{{0}},
		Input:             sRoute,
	}

	vc := &loggingVCursor{
		resolvedTargetTabletType: topodatapb.TabletType_PRIMARY,
		ksShardMap: map[string][]string{
			"sks1": {"-20", "20-"},
			"sks2": {"-20", "20-"},
			"uks1": {"0"},
			"uks2": {"0"},
		},
	}
	vc.results = []*sqltypes.Result{
		sqltypes.MakeTestResult(sqltypes.MakeTestFields("id", "int64"), "1")}

	_, err := ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		// the select query
		`ResolveDestinations sks2 [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard sks2.-20: dummy_select {} sks2.20-: dummy_select {} false false`,

		// the query exec
		`ResolveDestinations sks1 [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`,
		`ExecuteMultiShard sks1.-20: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`})

	vc.Rewind()
	err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error {
		return nil
	})
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		// the select query
		`ResolveDestinations sks2 [] Destinations:DestinationAllShards()`,
		`StreamExecuteMulti dummy_select sks2.-20: {} sks2.20-: {} `,

		// the query exec
		`ResolveDestinations sks1 [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`,
		`ExecuteMultiShard sks1.-20: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`})

	// sks1 and uks2
	ins.Input = uRoute

	vc.Rewind()
	_, err = ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		// the select query
		`ResolveDestinations uks2 [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard uks2.0: dummy_select {} false false`,

		// the query exec
		`ResolveDestinations sks1 [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`,
		`ExecuteMultiShard sks1.-20: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`})

	vc.Rewind()
	err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error {
		return nil
	})
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		// the select query
		`ResolveDestinations uks2 [] Destinations:DestinationAllShards()`,
		`StreamExecuteMulti dummy_select uks2.0: {} `,

		// the query exec
		`ResolveDestinations sks1 [value:"0"] Destinations:DestinationKeyspaceID(166b40b44aba4bd6)`,
		`ExecuteMultiShard sks1.-20: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`})

	// uks1 and sks2
	ins = &Insert{
		Opcode:   InsertUnsharded,
		Keyspace: uks1.Keyspace,
		Query:    "dummy_insert",
		Table:    uks1.Tables["s1"],
		Prefix:   "prefix ",
		Suffix:   " suffix",
		Input:    sRoute,
	}

	vc.Rewind()
	_, err = ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		// the select query
		`ResolveDestinations sks2 [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard sks2.-20: dummy_select {} sks2.20-: dummy_select {} false false`,

		// the query exec
		`ResolveDestinations uks1 [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard uks1.0: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`})

	vc.Rewind()
	err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error {
		return nil
	})
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		// the select query
		`ResolveDestinations sks2 [] Destinations:DestinationAllShards()`,
		`StreamExecuteMulti dummy_select sks2.-20: {} sks2.20-: {} `,

		// the query exec
		`ResolveDestinations uks1 [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard uks1.0: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`})

	// uks1 and uks2
	ins.Input = uRoute

	vc.Rewind()
	_, err = ins.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false)
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		// the select query
		`ResolveDestinations uks2 [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard uks2.0: dummy_select {} false false`,

		// the query exec
		`ResolveDestinations uks1 [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard uks1.0: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`})

	vc.Rewind()
	err = ins.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, func(result *sqltypes.Result) error {
		return nil
	})
	require.NoError(t, err)
	vc.ExpectLog(t, []string{
		// the select query
		`ResolveDestinations uks2 [] Destinations:DestinationAllShards()`,
		`StreamExecuteMulti dummy_select uks2.0: {} `,

		// the query exec
		`ResolveDestinations uks1 [] Destinations:DestinationAllShards()`,
		`ExecuteMultiShard uks1.0: prefix values (:_c0_0) suffix {_c0_0: type:INT64 value:"1"} true true`})
}


text:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AlunosComponent } from './alunos/alunos.component';
import Backendless from 'backendless';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { environment } from '../environments/environment';
import { HeaderComponent } from './navigation/header/header.component';
import { CustomMaterialModule } from './shared/custom.material.module';
import { NovoAlunoComponent } from './novo-aluno/novo-aluno.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

Backendless.initApp(environment.backendless.APP_ID, environment.backendless.API_KEY);

@NgModule({
  declarations: [
    AppComponent,
    AlunosComponent,
    HeaderComponent,
    NovoAlunoComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    CustomMaterialModule,
    FormsModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


text:
require 'spec_helper'

class CommandRun
  attr_accessor :stdout, :stderr, :exitstatus

  def initialize(args)
    out = StringIO.new
    err = StringIO.new

    $stdout = out
    $stderr = err

    begin
      Vcloud::EdgeGateway::Cli.new(args).run
      @exitstatus = 0
    rescue SystemExit => e
      # Capture exit(n) value.
      @exitstatus = e.status
    end

    @stdout = out.string.strip
    @stderr = err.string.strip

    $stdout = STDOUT
    $stderr = STDERR
  end
end

describe Vcloud::EdgeGateway::Cli do
  subject { CommandRun.new(args) }

  describe "normal usage" do
    let(:mock_configure) {
      double(:configure, :update => {})
    }

    context "when given a single config file" do
      let(:args) { %w{config.yaml} }

      it "should pass single argument, call update without any args, and exit normally" do
        expect(Vcloud::EdgeGateway::Configure).to receive(:new).
          with('config.yaml').and_return(mock_configure)
        expect(mock_configure).to receive(:update).with(no_args)
        expect(subject.exitstatus).to eq(0)
      end
    end

    context "when given --template-vars and config file" do
      let(:args) { %w{--template-vars vars.yaml config.yaml} }

      it "should pass two arguments and exit normally" do
        expect(Vcloud::EdgeGateway::Configure).to receive(:new).
          with('config.yaml', 'vars.yaml').and_return(mock_configure)
        expect(mock_configure).to receive(:update)
        expect(subject.exitstatus).to eq(0)
      end
    end

    context "when given --dry-run and config file" do
      let(:args) { %w{--dry-run config.yaml} }

      it "should call update(true) and exit normally" do
        expect(Vcloud::EdgeGateway::Configure).to receive(:new).
          with('config.yaml').and_return(mock_configure)
        expect(mock_configure).to receive(:update).with(true)
        expect(subject.exitstatus).to eq(0)
      end
    end

    context "when asked to display version" do
      let(:args) { %w{--version} }

      it "should not call Configure" do
        expect(Vcloud::EdgeGateway::Configure).not_to receive(:new)
      end

      it "should print version and exit normally" do
        expect(subject.stdout).to eq(Vcloud::EdgeGateway::VERSION)
        expect(subject.exitstatus).to eq(0)
      end
    end

    context "when asked to display help" do
      let(:args) { %w{--help} }

      it "should not call Configure" do
        expect(Vcloud::EdgeGateway::Configure).not_to receive(:new)
      end

      it "should print usage and exit normally" do
        expect(subject.stderr).to match(/\AUsage: \S+ \[options\] config_file\n/)
        expect(subject.exitstatus).to eq(0)
      end
    end
  end

  describe "diff output" do
    shared_examples "diff with stdout contents" do |expected_stdout|
      it "should output diff to stdout" do
        expect(Vcloud::EdgeGateway::Configure).to receive(:new).
          with('config.yaml').and_return(mock_configure)
        expect(subject.stdout).to eq(expected_stdout.chomp)
        expect(subject.exitstatus).to eq(0)
      end
    end

    context "when diff is empty" do
      let(:mock_configure) {
        double(:configure, :update => {})
      }

      context "when given config (colour doesn't matter)" do
        let(:args) { %w{config.yaml} }

        it_behaves_like "diff with stdout contents", ""
      end
    end

    context "when diff contains two services with three types of changes" do
      shared_examples "diff with colour output" do
        include_examples "diff with stdout contents", <<-EOS.chomp
\033[31m- FirewallService.IsEnabled: true\033[0m
\033[32m+ FirewallService.LogDefaultAction: false\033[0m
\033[31m- NatService.IsEnabled: true\033[0m
\033[32m+ NatService.IsEnabled: false\033[0m
        EOS
      end

      shared_examples "diff without colour output" do
        include_examples "diff with stdout contents", <<-EOS.chomp
- FirewallService.IsEnabled: true
+ FirewallService.LogDefaultAction: false
- NatService.IsEnabled: true
+ NatService.IsEnabled: false
        EOS
      end

      let(:mock_configure) {
        double(:configure, :update => {
          :FirewallService => [
            ["-", "IsEnabled", "true"],
            ["+", "LogDefaultAction", "false"],
          ],
          :NatService => [
            ["~", "IsEnabled", "true", "false"],
          ],
        })
      }

      context "STDOUT is not redirected" do
        before(:each) {
          STDOUT.stub(:tty?).and_return(true)
        }

        context "when colour argument is not specified" do
          let(:args) { %w{config.yaml} }

          it_behaves_like "diff with colour output"
        end

        context "when given --no-colour" do
          let(:args) { %w{--no-colour config.yaml} }

          it_behaves_like "diff without colour output"
        end
      end

      context "STDOUT is redirected" do
        before(:each) {
          STDOUT.stub(:tty?).and_return(false)
        }

        context "when colour argument is not specified" do
          let(:args) { %w{config.yaml} }

          it_behaves_like "diff without colour output"
        end

        context "when given --colour" do
          let(:args) { %w{--colour config.yaml} }

          it_behaves_like "diff with colour output"
        end
      end
    end
  end

  describe "incorrect usage" do
    shared_examples "print usage and exit abnormally" do |error|
      it "should not call Configure" do
        expect(Vcloud::EdgeGateway::Configure).not_to receive(:new)
      end

      it "should print error message and usage" do
        expect(subject.stderr).to match(/\A\S+: #{error}\nUsage: \S+/)
      end

      it "should exit abnormally for incorrect usage" do
        expect(subject.exitstatus).to eq(2)
      end
    end

    context "when run without any arguments" do
      let(:args) { %w{} }

      it_behaves_like "print usage and exit abnormally", "must supply config_file"
    end

    context "when given a multiple config files" do
      let(:args) { %w{one.yaml two.yaml} }

      it_behaves_like "print usage and exit abnormally", "must supply config_file"
    end

    context "when given an unrecognised argument" do
      let(:args) { %w{--this-is-garbage} }

      it_behaves_like "print usage and exit abnormally", "invalid option: --this-is-garbage"
    end
  end
end


text:
/**
 * This class is generated by jOOQ
 */
package de.piratenpartei.berlin.ldadmin.dbaccess.generated.routines;

/**
 * This class is generated by jOOQ.
 */
@javax.annotation.Generated(value    = { "http://www.jooq.org", "3.4.4" },
                            comments = "This class is generated by jOOQ")
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class DelegationInfo extends org.jooq.impl.AbstractRoutine<de.piratenpartei.berlin.ldadmin.dbaccess.generated.udt.records.DelegationInfoTypeRecord> {

	private static final long serialVersionUID = -1297688832;

	/**
	 * The parameter delegation_info.RETURN_VALUE.
	 */
	public static final org.jooq.Parameter<de.piratenpartei.berlin.ldadmin.dbaccess.generated.udt.records.DelegationInfoTypeRecord> RETURN_VALUE = createParameter("RETURN_VALUE", de.piratenpartei.berlin.ldadmin.dbaccess.generated.udt.DelegationInfoType.DELEGATION_INFO_TYPE.getDataType());

	/**
	 * The parameter delegation_info.member_id_p.
	 */
	public static final org.jooq.Parameter<java.lang.Integer> MEMBER_ID_P = createParameter("member_id_p", org.jooq.impl.SQLDataType.INTEGER);

	/**
	 * The parameter delegation_info.unit_id_p.
	 */
	public static final org.jooq.Parameter<java.lang.Integer> UNIT_ID_P = createParameter("unit_id_p", org.jooq.impl.SQLDataType.INTEGER);

	/**
	 * The parameter delegation_info.area_id_p.
	 */
	public static final org.jooq.Parameter<java.lang.Integer> AREA_ID_P = createParameter("area_id_p", org.jooq.impl.SQLDataType.INTEGER);

	/**
	 * The parameter delegation_info.issue_id_p.
	 */
	public static final org.jooq.Parameter<java.lang.Integer> ISSUE_ID_P = createParameter("issue_id_p", org.jooq.impl.SQLDataType.INTEGER);

	/**
	 * The parameter delegation_info.simulate_trustee_id_p.
	 */
	public static final org.jooq.Parameter<java.lang.Integer> SIMULATE_TRUSTEE_ID_P = createParameter("simulate_trustee_id_p", org.jooq.impl.SQLDataType.INTEGER);

	/**
	 * The parameter delegation_info.simulate_default_p.
	 */
	public static final org.jooq.Parameter<java.lang.Boolean> SIMULATE_DEFAULT_P = createParameter("simulate_default_p", org.jooq.impl.SQLDataType.BOOLEAN);

	/**
	 * Create a new routine call instance
	 */
	public DelegationInfo() {
		super("delegation_info", de.piratenpartei.berlin.ldadmin.dbaccess.generated.DefaultSchema.DEFAULT_SCHEMA, de.piratenpartei.berlin.ldadmin.dbaccess.generated.udt.DelegationInfoType.DELEGATION_INFO_TYPE.getDataType());

		setReturnParameter(RETURN_VALUE);
		addInParameter(MEMBER_ID_P);
		addInParameter(UNIT_ID_P);
		addInParameter(AREA_ID_P);
		addInParameter(ISSUE_ID_P);
		addInParameter(SIMULATE_TRUSTEE_ID_P);
		addInParameter(SIMULATE_DEFAULT_P);
	}

	/**
	 * Set the member_id_p parameter IN value to the routine
	 */
	public void setMemberIdP(java.lang.Integer value) {
		setValue(de.piratenpartei.berlin.ldadmin.dbaccess.generated.routines.DelegationInfo.MEMBER_ID_P, value);
	}

	/**
	 * Set the member_id_p parameter to the function to be used with a {@link org.jooq.Select} statement
	 */
	public void setMemberIdP(org.jooq.Field<java.lang.Integer> field) {
		setField(MEMBER_ID_P, field);
	}

	/**
	 * Set the unit_id_p parameter IN value to the routine
	 */
	public void setUnitIdP(java.lang.Integer value) {
		setValue(de.piratenpartei.berlin.ldadmin.dbaccess.generated.routines.DelegationInfo.UNIT_ID_P, value);
	}

	/**
	 * Set the unit_id_p parameter to the function to be used with a {@link org.jooq.Select} statement
	 */
	public void setUnitIdP(org.jooq.Field<java.lang.Integer> field) {
		setField(UNIT_ID_P, field);
	}

	/**
	 * Set the area_id_p parameter IN value to the routine
	 */
	public void setAreaIdP(java.lang.Integer value) {
		setValue(de.piratenpartei.berlin.ldadmin.dbaccess.generated.routines.DelegationInfo.AREA_ID_P, value);
	}

	/**
	 * Set the area_id_p parameter to the function to be used with a {@link org.jooq.Select} statement
	 */
	public void setAreaIdP(org.jooq.Field<java.lang.Integer> field) {
		setField(AREA_ID_P, field);
	}

	/**
	 * Set the issue_id_p parameter IN value to the routine
	 */
	public void setIssueIdP(java.lang.Integer value) {
		setValue(de.piratenpartei.berlin.ldadmin.dbaccess.generated.routines.DelegationInfo.ISSUE_ID_P, value);
	}

	/**
	 * Set the issue_id_p parameter to the function to be used with a {@link org.jooq.Select} statement
	 */
	public void setIssueIdP(org.jooq.Field<java.lang.Integer> field) {
		setField(ISSUE_ID_P, field);
	}

	/**
	 * Set the simulate_trustee_id_p parameter IN value to the routine
	 */
	public void setSimulateTrusteeIdP(java.lang.Integer value) {
		setValue(de.piratenpartei.berlin.ldadmin.dbaccess.generated.routines.DelegationInfo.SIMULATE_TRUSTEE_ID_P, value);
	}

	/**
	 * Set the simulate_trustee_id_p parameter to the function to be used with a {@link org.jooq.Select} statement
	 */
	public void setSimulateTrusteeIdP(org.jooq.Field<java.lang.Integer> field) {
		setField(SIMULATE_TRUSTEE_ID_P, field);
	}

	/**
	 * Set the simulate_default_p parameter IN value to the routine
	 */
	public void setSimulateDefaultP(java.lang.Boolean value) {
		setValue(de.piratenpartei.berlin.ldadmin.dbaccess.generated.routines.DelegationInfo.SIMULATE_DEFAULT_P, value);
	}

	/**
	 * Set the simulate_default_p parameter to the function to be used with a {@link org.jooq.Select} statement
	 */
	public void setSimulateDefaultP(org.jooq.Field<java.lang.Boolean> field) {
		setField(SIMULATE_DEFAULT_P, field);
	}
}