MySQL table names are case-sensitive, but the fake
DUAL table is case-insensitive. So, I've changed the parser
to always lower case this id.
We don't want to treat this as a keyword because the AST
then tries to escape it with back-quotes. So, it's better
to just treat this as a case-insensitive ID.
This feature is needed for improving the usability of
ExecuteBatch. People may want a dup key error from insert
to be ignored so that they can follow it with other statements.
In the implementation, there's one caveat I had to handle, which
is that the ignore should be removed if it's an upsert. Otherwise,
we never get the dup key errror.
Upsert is mostly feature complete. There are still two
issues to resolve:
1. RowsAffected is returned as 0 if no rows were modified. So, we cannot
assume that no rows were matched. So, the value cannot be used to verify
if the dup key matched a pk or a unique key.
2. I mistooke VALUES to be VALUE, and coded defense against using that
construct in the parser. It turns out that the parser already allows use
of VALUES. So, I'll have to find a different way to prevent that usage
for upserts.
vttablet cannot support those two functions in upserts.
Marking them as keywords automatically prevents their use.
This way, we don't have to explicitly look for these keywords
inside upserts to prevent them. If/when we decide to support
them, we can add these keywords to the keyword_as_func
rule in the parser.
Fix for issue https://github.com/youtube/vitess/issues/797.
Names that used keywords were not always getting back-quoted
correctly during codegen. This is a comprehensive fix that
covers all such possible cases.
This fixes issue https://github.com/youtube/vitess/issues/798
where a construct like "a - -b" produced incorrect code.
I also found a related bug where a construct like "- -a"
also produced incorrect code.
This is also a potential vulnerability because "--" is
treated as a comment.
In short, the tableacl configuration will be represented as a
tableacl.proto. tableacl module holds a global "currentACL" instance
which maps a table group to its ACLs.
1. Introduce tableacl.proto which defines acl per table group.
A table group either contains only one table or many tables
that share the same name prefix.
2. Remove "All" and "AllString" funcs from acl.Factory interface.
This addresses https://github.com/youtube/vitess/issues/767
as well as other situations where there's possibility of
indefinite nesting of SQL constructs. There may be other
non-aprentheszed constructs that allow nesting, but this fix
doesn't address them for now.
I've also made a few lint fixes. sql.go is still in violation,
but that requires bigger work.
The values within each row of a QueryResult were being JSON-encoded as
base64 byte arrays for every type. This JSON encoding was only being
used for tests, until the recent addition of vtctl commands that display
JSON-encoded QueryResults.
Now that we are displaying these to humans, we should display the
results as strings instead of as byte arrays.
As part of removing googleBinlogEvent parsing support, I reworked the
binlog_streamer_test to use fake events instead of real ones. The actual
parsing of real events is already tested in its own unit test. Using
fake events simplifies the binlog_streamer_test, which really is only
meant to test the logic for converting a stream of events into a stream
of transaction objects.
In order to support split queries for map-reduce jobs,
we need a way to send queries to specific shards. But
we cannot assume that there will be physical keyspace_id
column in the table, which will prevent us from specifying
a keyrange on it.
So, we introduce the KEYRANGE construct which is a boolean
expression that VTGate can use to match the range to a set
of shards. Since the construct is not understood by VTTablet
or MySQL, VTGate will also strip the construct before passing
the query down.
For owned indexes, we have to know which rows are going
to be deleted so that we can delete the corresponding vindex
entries. So, deletes need to run a subquery to identify
these rows. An empty subquery means that the table does
not own any vindexes.
Since each keyspace can have its own ShardKey, it's not a good
ShardKey as a special name because the index may also need to map
to a physical table, which will cause conflicts. Instead, and index
now has a Type field, which can be ShardKey or Lookup.