CockroachDB: select and cast byte -> string type - cockroachdb

I've got a query storing a UUIDv4 as a byte type in CockroachDB (v1.0). Its generated with Cockroach's documented 'uuid_v4()' function. When making selections, the results will return with the byte-typed format, like so:
"\x9d\xce`\xb3p\x9aKB\xbe\xba\xeb\xec~\x9e\xfb\x93"
while the goal is to have it output a string uuidv4, like:
"abcd-12345-asdifoekc"
I've read the casting docs on: https://www.cockroachlabs.com/docs/data-types.html#data-type-conversions--casts but still cannot figure out how to do this conversion during a SELECT statement.

Use the from_uuid() builtin, as follows:
root#:26257/> SELECT from_uuid(uuid_v4());
+--------------------------------------+
| from_uuid(uuid_v4()) |
+--------------------------------------+
| 4817bb15-4d93-4b77-b7d1-1e5cfb8360e3 |
+--------------------------------------+
(1 row)

Related

Google Spreadsheet API returning grid limits error

I am trying to update a Google Sheet using the Ruby API (that is just a wrapper around the SheetsV4 API)
I am running into the following error
Google::Apis::ClientError: badRequest: Range ('MySheet'!AA1) exceeds grid limits. Max rows: 1000, max columns: 26
I have found references of this problem on the google forum, however there did not seem to be a solution to the problem other that to use a different method to write to the spreadsheet.
The thing is, I need to copy an existing spreadsheet template, and enter my raw data in various sheets. So far I have been using this code (where service is a client of the Ruby SheetsV4 API)
def write_table(values, sheet: 'Sheet1', column: 1, row: 1, range: nil, value_input_option: 'RAW')
google_range = begin
if range
"#{sheet}!#{range}"
elsif column && row
"#{sheet}!#{integer_to_A1_notation(column)}#{row}"
end
end
value_range_object = ::Google::Apis::SheetsV4::ValueRange.new(
range: google_range, values: values
)
service.update_spreadsheet_value(spreadsheet_id,
google_range,
value_range_object,
value_input_option: value_input_option
)
end
It was working quite well so far, but after adding more data to my extracts, I went over the 26th column, (columns AA onwards) and now I am getting the error.
Is there some option to pass to update_spreadsheet_value so we can raise this limit ?
Otherwise, what is the other way to write to the spreadsheet using append ?
EDIT - A clear description of my scenario
I have a template Google spreadsheet with 8 sheets(tabs), 4 of which are titled RAW-XX and this is where I try to update my data.
At the beginning, those raw tabs only have headers on 30 columns (A1 --> AD1)
My code needs to be able to fill all the cells A2 --> AD42
(1) for the first time
(2) and my code needs to be able to re-run again to replace those values by fresh ones, without appending
So basically I was thinking of using update_spreadsheet_value rather than append_xx because of the requirement (2). But becuase of this bug/limitation (unclear) in the API, this does not work. ALso important to note : I am not actually updating all those 30 columns in one go, but actually in several calls to the update method (with up to 10 columns each time)
I've thought that
- Maybe I am missing an option to send to the Google API to allow more than 26 columns in one go ?
- Maybe this is actually an undocumented hard limitation of the update API
- Maybe I can resort to deleting existing data + using append
EDIT 2
Suppose I have a template at version 1 with multiple sheets (Note that I am using =xx to indicate a formula, and [empty] to indicate there is nothing in the cell, and 1 to indicate the raw value "1" was supplied
Sheet1 - RAW
RAW Number of foos | RAW Number of Bars |
[empty] | [empty] |
Sheet2 - FORMATTED
Number of foos | Number of Bars
='Sheet1 - RAW'!A2 | ='Sheet1 - RAW'B2
Now I call my app "for the first time", this copies the existing template to a new file "generated_spreadsheet" and injects data in the RAW sheet. It turns out at this moment, my app says there is 1 foo and 0 bar
Sheet1 - RAW
RAW Number of foos | RAW Number of Bars |
1 | 0 |
Sheet2 - FORMATTED
Number of foos | Number of Bars
='Sheet1 - RAW'!A2 | ='Sheet1 - RAW'!B2
Maybe if I call my app later, maybe the template AND the data have changed in between, so I want to REPLACE everything in my "generated_spreadsheet"
The new template has become in between
Sheet1 - RAW
RAW Number of foos | RAW Number of Bars |
[empty] | [empty] |
Sheet2 - FORMATTED
Number of foos | Number of Bars | All items
='Sheet1 - RAW'!A2 | ='Sheet1 - RAW'!B2 | =A2 + B2
Suppose now my app says there is still 1 foo and the number of bars went from 0 to 2, I want to update the "generated_spreadsheet" so it looks like
Sheet1 - RAW
RAW Number of foos | RAW Number of Bars |
1 | 3 |
Sheet2 - FORMATTED
Number of foos | Number of Bars | All items
='Sheet1 - RAW'!A2 | ='Sheet1 - RAW'!B2 | =A2 + B2
How about using values.append? In my environment, I also experienced the same situation with you. In order to avoid this issue, I used values.append.
Please modify as follows and try it again.
From:
service.update_spreadsheet_value(
To:
service.append_spreadsheet_value(
Reference:
Method: spreadsheets.values.append
If this was not the result you want, I'm sorry.
this because out of range.
AA1 means column is AA, also means 27, so this start point AA1 not exist, that's why you met this error.
you can try Z1, this should be ok.
worksheet.resize(2000)
will resize your sheet 2000 rows
It happened to me as well when I didn't have the empty columns (I removed all the empty columns from the spreadsheet). I simply added an empty one next to my last column and it works.

Relational algebra, Find unique Names

Say I have the following relational schema:
+-------+------------+
| Name | Subject |
+--------------------+
| 1 | A |
| 1 | B |
| 1 | C |
| 2 | D |
| 2 | E |
| 3 | F |
| 4 | G |
| 5 | H |
| 5 | I |
+-------+------------+
and I seek these tuples:
3
4
How to get unique names for people only doing 1 subject?
Here's an example based on what AntC described:
NS={
name:string, subject:string
'1' , 'A'
'1' , 'B'
'1' , 'C'
'2' , 'D'
'2' , 'E'
'3' , 'F'
'4' , 'G'
'5' , 'H'
'5' , 'I'
}
(π name NS) - π name (σ s!=subject ((ρ s←subject NS) ⨝ NS))
If you want to test this out you can try it at:
https://dbis-uibk.github.io/relax/calc.htm
Choc Boo, welcome to stackoverflow [relational-algebra]. I strongly suggest you find yourself a textbook or online learning resource that will take you step-by-step -- preferably something you can share with other learners.
Are you sure it's RA you want to learn? Or SQL? They're very different: as a noob, learning one will probably completely confuse you wrt the other. (The connection between them won't become clear until you're much deeper in.)
There are places you can run RA online. But beware they use a specific dialect of RA, which might not be the one you're trying to learn.
Your query could perhaps be expressed as:
"Return all Names that appear in a single tuple."
Note I didn't mention "only doing 1 subject": a relation is a set; if any Name appears more than once it must be that it appears with multiple Subjects.
There's a 'quick and dirty' way to an answer: for each Name count how many tuples; restrict the result to return only those with count == 1. (That way will need using an advanced RA operator for counting.)
There's a longer-winded way that uses only more primitive operators: take two versions of your relation; pair each tuple with each from the other version; the Names that appear in more than one tuple will pair up in multiple ways same-Name-different-Subject; those are the Names you don't want.
What do I mean by "two versions"? Find out about the Rename operation (ρ). What do I mean by "pair ... with ..."? Find out about the Join operation (⋈). What do I mean by "don't want"? Find out about the set difference operator (-): I said relations are sets.

How is the | symbol read in Elm?

Consider the following example code:
-- Update the fields of a record. (It must have the fields already.)
{ person |
name = "George" }
-- Update multiple fields at once, using the current values.
{ particle |
position = particle.position + particle.velocity,
velocity = particle.velocity + particle.acceleration }
Source: Learn Elm in X Minutes
How is one supposed to read | in this example, and in Elm generally?
I'm familiar with it in set-builder notation as "where" / "such that", and in list comprehensions in Haskell it has a very similar purpose, e.g.
[ x*2 | x <- [1..10] ]
is logically equivalent to
source: Learn You A Haskell
(Obviously I'm also familiar with its use as the unary "or" operator in C-like languages)
What about something like type Msg = Increment | Decrement ?
Source: https://guide.elm-lang.org
Or, in this example when discussing Union Types:
type Boolean
= T
| F
| Not Boolean
| And Boolean Boolean
| Or Boolean Boolean
In types I read it as 'or'. In the counter example:
type Msg = Increment | Decrement
I would read it as "a Msg is Increment or Decrement". In a slightly more complex but still common example of the Result type:
type Result error value
= Ok value
| Err error
I would read "a Result is either Ok with a value or Err with an error".
In the example you give of the record update syntax, I would read it as 'with' rather than 'where'. For example:
{ person | name = "George" }
is "the person value with its name field set to "George"" (rather than "where the name = 'George'" which seems to imply that you're filtering based on what values are in person). This one is I think more ambiguous than the type case though.

Enums in F# for strings

I'm working on a legacy database with no systems to which I can modify. Because of type providers I decided to use F#. It's not so simple now that I'm into it. How do I structure a field in my DB that has only the following strings? It's sort of like an ENUM. I've tried the following but haven't quite gotten it.
Attempt 1
type SuspendedDriver = "SI"
type ActiveDriver = "IMPRESO"
type Applicant = "NO"
type TemporaryDriver = "TEMP"
type Uncertain = "NULL"
type DriverStatus =
| SuspendedDriver
| ActiveDriver
| Applicant
| TemporaryDriver
| Uncertain
type Driver = {
status : DriverStatus
}
Error
Error FS0618: Invalid literal in type (FS0618) (ScriptTest)
Attempt 2
type DriverStatus =
| SuspendedDriver = "SI"
| ActiveDriver = "IMPRESO"
| Applicant = "NO"
| TemporaryDriver = "TEMP"
| Uncertain = "NULL"
Error
Error FS0951: Literal enumerations must have type int, uint, int16,
uint16, int64, uint64, byte, sbyte or char (FS0951) (ScriptTest)
As mentioned in the comment, you cannot define an enum that has values erased to strings. Enums can only be integers (of various types).
Using enums in an ugly way
You could use the actual names of the enum fields and then parse them using Enum.Parse, but that's probably not good idea, because the enum cases would be fairly obscure codes. But just for the record, the following works:
type DriverStatus =
| SI = 0
System.Enum.Parse(typeof<DriverStatus>, "SI") :?> DriverStatus
Cleaner parsing into discriminated union
In practice, I would do what Sam recommends and write a function to parse the string from the database. This has the advantage that you'll need to figure out what to do with errors in the database (the value can always be something wrong):
type DriverStatus =
| SuspendedDriver
| ActiveDriver
let parseDriverStatus = function
| "SI" -> SuspendedDriver
| "IMPRESO" -> ActiveDriver
| code -> failwith (sprintf "Wrong driver code! %s" code)
Using the cool Enum SQL provider
Finally, if you happen to be using MS SQL database, then the SQL Command Provider project has a neat feature that lets you automatically import enum-like types from SQL database itself, which might actually be exactly what you need in this case.

Group and Count an Array of Structs

Ruby noob here!
I have an array of structs that look like this
Token = Struct.new(:token, :ordinal)
So an array of these would look like this, in tabular form:
Token | Ordinal
---------------
C | 2
CC | 3
C | 5
And I want to group by the "token" (i.e. the left hand column) of the struct and get a count, but also preserve the "ordinal" element. So the above would look like this
Token | Merged Ordinal | Count
------------------------------
C | 2, 5 | 2
CC | 3 | 1
Notice that the last column is a count of the grouped tokens and the middle column merges the "ordinal". The first column ("Token") can contain a variable number of characters, and I want to group on these.
I have tried various methods, using group_by (I can get the count, but not the middle column), inject, iterating (does not seem very functional) but I just can't get it right, partly because I don't have a good grasp of Ruby and the available operations / functions.
I have also had a good look around SO, but I am not getting very far.
Any help, pointers would be much appreciated!
Use Enumerable#group_by to do the grouping for you and use the resulting hash to get what you want with map or similar.
structs.group_by(&:token).map do |token, with_same_token|
[token, with_same_token.map(&:ordinal), with_same_token.size]
end

Resources