Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identify if a column is Virtual in Snowflake

Snowflake does not document its Virtual Column capability that uses the AS clause. I am doing a migration and needing to filter out virtual columns programatically.

Is there any way to identify that a column is virtual? The Information Schema.COLLUMNS view shows nothing different between a virtual and non-virtual column definition.

like image 628
Rob D Avatar asked Aug 06 '21 18:08

Rob D


People also ask

What is virtual column in Snowflake?

Derived columns or computed columns are virtual columns that are not physically stored in the table. Their values are re-calculated every time they are referenced in a query. In other word, Derived columns are columns that you derive from other previously computed column in same query context.

What is virtual column in database?

In relational databases a virtual column is a table column whose value is automatically computed using other columns values, or another deterministic expression.


2 Answers

There is a difference between column defined as DEFAULT and VIRTUAL COLUMN(aka computed, generated column):

Virtual column

CREATE OR REPLACE TABLE T1(i INT, calc INT AS (i*i));
INSERT INTO T1(i) VALUES (2),(3),(4);
SELECT * FROM T1;

enter image description here

When using AS (expression) syntax the expression is not visible inCOLUMN_DEFAULT:

enter image description here


DEFAULT Expression

In case of the defintion DEFAULT (expression):

CREATE OR REPLACE TABLE T2(i INT, calc INT DEFAULT (i*i));
INSERT INTO T2(i) VALUES (2),(3),(4);
SELECT * FROM T2;

It is visible in COLUMN_DEFAULT:

SELECT * 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'T2';

enter image description here


Comparing side-by-side with SHOW COLUMNS:

SHOW COLUMNS LIKE 'CALC';
-- kind: VIRTUAL_COLUMN

enter image description here

One notable difference between them is that virtual column cannot be updated:

UPDATE T1
SET calc  = 1;
-- Virtual column 'CALC' is invalid target.

UPDATE T2
SET calc = 1;
-- success
like image 144
Lukasz Szozda Avatar answered Oct 18 '22 21:10

Lukasz Szozda


How about using SHOW COLUMNS ? you should identify them when expression field is not null.

create table foo (id bigint, derived bigint as (id * 10));
insert into foo (id) values (1), (2), (3);

SHOW COLUMNS IN TABLE foo;
SELECT "table_name", "column_name", "expression" FROM table(result_scan(last_query_id()));

| table_name | column_name | expression     |
| ---------- | ----------- | -------------- |
| FOO        | ID          | null           |
| FOO        | DERIVED     | ID*10          |
like image 35
CMe Avatar answered Oct 18 '22 22:10

CMe