Making A Copy and Deep Copy of a Table

Hello,

I’m trying to relate C++ concepts to q. I read that “In q, copy is done on a write operation”. I am looking to make a deep and shallow copy of a table. I do not want to incur a write operation, or write my table to disk to make my copy.

I’ve been playing around below, and I’m wondering if I can make a deep copy without saving my table (t1) to disk. Please see below:

Our base table:

q)n:1000q)t2:([id:til n] sym:n?2; price:n?90.)q)t1:( t2$id:til n; sym:n?2; price:n?90.)`

  1. Making a shallow copy without a write operation to the original table:

q)t3:flip idsymprice!“jsf”$:()q)t3id sym price------------q)insert[t3;t1]q)meta t3c | t f a-----| -----id | j sym | s price| f q)-16!t1 / This is a shallow copy since it has no foreign key relation to t2 (and is not a reference to t1)1i

``
2. Making a deep copy (maintain foreign key relationship):

q):ourTable set t1 / First save t1 down:ourTableq)t4:get :ourTable / Then get it as t4.q)meta t4c | t f a-----| ------id | j t2 sym | s price| f q)-16!t11i / Not a reference to t1`

Is there any way to create a deep copy without saving my table t1 to disk?

Cheers

Try this: -9!-8!t

Hi Tom,

“Copy on write” means that you never have to worry about creating a physical copy of your data in order to protect it from unwanted modifications.

For example:

q)l1:l2:1 2 3 4 5 // l1 and l2 refers to the same data

q)l2[2]: 30 // l2 will be the modified copy of l1

q)l1 // l1 is the same

1 2 3 4 5

q)l2 // only l2 has the change

1 2 30 4 5

The same works with tables and any other data.

Regards,

Andras

This creates a shallow copy, not a deep copy.

Thanks for your response Andras. But if I do want a physical copy (a deep copy), how can I get one without performing a write or a get on a saved table?

See Flying’s answer.

Flying’s approach seems to create a shallow copy as opposed to a deep copy, as the foreign key relationship after serializing and deserializing vanishes.

I am wondering how I create a deep copy (i.e. keep the foreign key relation).

q)meta t1 / Original table with foreign key relationc | t f a-----| ------id | j t2 sym | s price| f q)meta -9!-8!t1 / Flying's approach, creating a table without a foreign key relationc | t f a-----| -----id | j sym | s price| f

What am I not understanding here?

Regards,

Tom

Hi,

-9!-8!x is the equivalent of getting data over IPC, so it creates a physical copy. Enums are converted back to their values over IPC, this is why you loose the foreign key relation. (Loosing the relation doesn’t mean it was a shallow copy.) You can recreate the link by a simple update:

update t2$id from t1

If you have a table with simple columns (like in your example), you can also force a physical copy like this:

t1c:t1; t1c[0]:t1c[0]

It will preserve the linkages to foreign tables too.

(Again, all of this is quite pointless, as we usually work against unnecessary RAM consumption.)

Regards,

András

Tom Tzad <tzadsauce@gmail.com> ezt írta (id?pont: 2019. nov. 16., Szo 19:37):

Flying’s approach seems to create a shallow copy as opposed to a deep copy, as the foreign key relationship after serializing and deserializing vanishes.

I am wondering how I create a deep copy (i.e. keep the foreign key relation).

q)meta t1 / Original table with foreign key relationc | t f a-----| ------id | j t2 sym | s price| f q)meta -9!-8!t1 / Flying's approach, creating a table without a foreign key relationc | t f a-----| -----id | j sym | s price| f

What am I not understanding here?

Regards,

Tom

Thanks for explaining Andras. Makes sense now.

Cheers,

Tom