--- title: "DESCRIBE" slug: "dev-database-reference-sql-describe" updated: 2026-10-30T18:19:11Z published: 2026-10-30T18:19:11Z canonical: "docs.vastdata.com/dev-database-reference-sql-describe" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.vastdata.com/llms.txt > Use this file to discover all available pages before exploring further. # DESCRIBE *Applies to VAST Cluster 5.5.* Shows a table's columns and their types. ## Syntax ``` DESCRIBE [TABLE] "/". SHOW "/".
``` ## Parameters and rules `DESCRIBE`, `DESCRIBE TABLE` and `SHOW` return the same result: one row per column, with six columns: | Result column | Holds | | --- | --- | | `column_name` | The column's name | | `column_type` | Its SQL type, for example `BIGINT`, `VARCHAR`, `STRUCT(lat DOUBLE)` or `TIMESTAMP WITH TIME ZONE` | | `null`, `key`, `default`, `extra` | In the captures, `null` was always `YES` and the others empty: the Query Engine has no `NOT NULL`, keys or defaults. | What `DESCRIBE` doesn't show: - **The sort key** of a sorted table. Use the Python SDK's table metadata ([data modeling](/develop/docs/dev-database-guides-data-modeling#sorted-tables)). - **The vector index** settings (metric and quantization). The vector column shows as `VECTOR(FLOAT, <dim>)`; see [vector search SQL](/develop/docs/dev-database-reference-sql-vector-search). - **Whether a column can be read** through the Query Engine. `MAP` and `TIMESTAMP WITH TIME ZONE` columns are listed, but selecting them fails; see [data types in SQL](/develop/docs/dev-database-reference-sql-data-types). `DESCRIBE` of a query, such as `DESCRIBE (SELECT rowid FROM ...)`, fails with an internal error message. Use `typeof()` instead: `SELECT typeof(rowid) FROM <table> LIMIT 1`. If a row filter or column mask applies to you on the table, `DESCRIBE` fails like any other statement on it ([vector search security](/develop/docs/dev-vector-search-operations-security#which-rules-work-with-vector-search)). With a column deny rule, `DESCRIBE` lists only the columns you may read. ## What happens on the cluster `DESCRIBE` reads the table's definition from the database's catalog. It reads no rows. ## Example The examples use the `run()` helper and the environment variables described in the [SQL reference](/develop/docs/dev-database-reference-sql-index#example-connect-and-use-a-transaction). This block connects, and creates the schema `docs_sql_describe` with a sorted table: ``` import os import re import adbc_driver_manager import adbc_driver_manager.dbapi as dbapi import adbc_driver_vastdb BUCKET = os.environ["VASTDB_BUCKET"] SCHEMA = f'"{BUCKET}/docs_sql_describe"' def connect(autocommit=True): return dbapi.connect( driver=adbc_driver_vastdb.get_driver_path(), db_kwargs={ "vast.db.endpoint": os.environ["QE_ENDPOINT"], "vast.db.access_key": os.environ["AWS_ACCESS_KEY_ID"], "vast.db.secret_key": os.environ["AWS_SECRET_ACCESS_KEY"], }, autocommit=autocommit, ) def server_message(e): """The server's message in a driver error, without the request ID or the echoed statement.""" text = re.sub(r"\[req=0x[0-9a-f]+\]: ", "", str(e)) found = (re.search(r'message: "(.*?)", request_id', text, re.S) or re.search(r"description: (.*)\)", text, re.S)) message = found.group(1) if found else text.strip().splitlines()[-1] message = re.sub(r"^Plan query: '.*?' failed with: ", "", message, flags=re.S) message = re.split(r"\\n|\n", message)[0].replace('\\"', '"') return message.replace(BUCKET, "") def run(sql): """Run one statement. Print the rows it returns, or the error.""" try: with conn.cursor() as cur: cur.execute(sql) rows = cur.fetchall() if cur.description else [] except (adbc_driver_manager.Error, OSError) as e: print(f"{type(e).__name__}: {server_message(e)}") else: print(rows) conn = connect() run(f"CREATE SCHEMA IF NOT EXISTS {SCHEMA}") run(f"CREATE TABLE IF NOT EXISTS {SCHEMA}.readings " "(id BIGINT, city VARCHAR, taken_at TIMESTAMP, location STRUCT(lat DOUBLE, lon DOUBLE), " "CONSTRAINT readings_sk SORT KEY (id))") ``` ``` [] [] ``` The three forms return the same rows. The sort key isn't listed: ``` run(f"DESCRIBE {SCHEMA}.readings") run(f"DESCRIBE TABLE {SCHEMA}.readings") run(f"SHOW {SCHEMA}.readings") ``` ``` [('id', 'BIGINT', 'YES', None, None, None), ('city', 'VARCHAR', 'YES', None, None, None), ('taken_at', 'TIMESTAMP', 'YES', None, None, None), ('location', 'STRUCT(lat DOUBLE, lon DOUBLE)', 'YES', None, None, None)] [('id', 'BIGINT', 'YES', None, None, None), ('city', 'VARCHAR', 'YES', None, None, None), ('taken_at', 'TIMESTAMP', 'YES', None, None, None), ('location', 'STRUCT(lat DOUBLE, lon DOUBLE)', 'YES', None, None, None)] [('id', 'BIGINT', 'YES', None, None, None), ('city', 'VARCHAR', 'YES', None, None, None), ('taken_at', 'TIMESTAMP', 'YES', None, None, None), ('location', 'STRUCT(lat DOUBLE, lon DOUBLE)', 'YES', None, None, None)] ``` To see the type of an expression, use `typeof()`: ``` run(f"INSERT INTO {SCHEMA}.readings VALUES (1, 'Lisbon', TIMESTAMP '2026-01-01 10:00:00', {{'lat': 38.7, 'lon': -9.1}})") run(f"SELECT typeof(rowid), typeof(location.lat) FROM {SCHEMA}.readings LIMIT 1") ``` ``` [(1,)] [('DECIMAL(38,0)', 'DOUBLE')] ``` Clean up: ``` run(f"DROP TABLE IF EXISTS {SCHEMA}.readings") run(f"DROP SCHEMA IF EXISTS {SCHEMA}") conn.close() ``` ``` [] [] ``` ## Errors | You wrote | Message | | --- | --- | | `DESCRIBE (SELECT ...)` | An internal error message that doesn't say what's wrong. Use `typeof()`. | ## Trino and Spark Trino and Spark have their own `DESCRIBE`, and Trino's `SHOW CREATE TABLE` also shows the sort columns; see [Trino](/develop/docs/dev-database-integrations-trino#sorted-tables) and [Spark](/develop/docs/dev-database-integrations-spark#spark-sql-and-dataframes). See also: [SHOW](/develop/docs/dev-database-reference-sql-show), [data types in SQL](/develop/docs/dev-database-reference-sql-data-types).