# quadbinQuerySource

You can use **quadbinQuerySource** to build layers and widgets using **custom SQL queries** powered by your data warehouse that contain:

* **Quadbin-based data:** a column containing a [Quadbin cell identifier](https://docs.carto.com/data-and-analysis/analytics-toolbox-for-bigquery/key-concepts/spatial-indexes#quadbin)
* **Point-based vector data**

{% hint style="success" %}
When you use point-based vector data in your quadbinQuerySource, CARTO will dynamically aggregate it into Quadbin cells, using an aggregation expression of your choice.
{% endhint %}

## Usage

```typescript
import {quadbinQuerySource} from '@carto/api-client';

const data = quadbinQuerySource({
  accessToken: 'XXX',
  connectionName: 'carto_dw',
  sqlQuery: 'SELECT * FROM carto-demo-data.demo_tables.quadbin_table',
  aggregationExp: 'SUM(population)'
});
```

## Options

```typescript
type QuadbinTableSourceOptions = {
  tableName: string;
  aggregationExp: string;
  aggregationResLevel?: number;
  spatialDataColumn?: string;
  filters?: Filters;
  filtersLogicalOperator?: 'and' | 'or'; 
  queryParameters?: QueryParameters;
};
```

* **tableName**: The fully qualified name (FQN) of the table you want to retrieve from your data warehouse. For example, for a BigQuery connection, `carto-demo-data.demo_tables.quadbin_sample` would be a valid table name.
* **aggregationExp:** A valid SQL expression that will define how this source aggregates quadbin cells starting from the base resolution into each parent quadbin cell in lower zoom levels. For example, for an `aggregationExp` containing `AVG(income)` , each parent quadbin cell will contain the average income from all its children.
  * For point-based, this defines the aggregation of the points for every zoom level.
* **aggregationResLevel** (optional): A number that expresses the resolution detail that will be used for each zoom level. By default this value is `6` .
  * Numbers lower than 6 will produce a less detailed visualization, with better performance.
  * Numbers higher than 6 will product a more detailed visualization, with worse performance.
* **spatialDataColumn** (optional): The name of the column that contains the geospatial information (geometries/geographies) that will be used for visualization and etc. By default, CARTO assumes this column is named `geom`.
* **filters** (optional): A valid [CARTO Filters](https://docs.carto.com/carto-for-developers/reference/filters/column-filters) object, used to perform server-side filtering of this data source with column-based filters.
* **filtersLogicalOperator** (optional): Indicates whether `filters` are applied following an `AND` logic or an `OR` logic.
* **queryParameters** (optional): If your `sqlQuery` contains query parameters, pass the values for each parameter in this field, following your data warehouse mechanism for query parameters, like named or positional parameters.

{% hint style="success" %}

## **About `queryParameters` and parameterized queries**

CARTO uses the native mechanisms available in each data warehouse to build parameterized queries, which prevents any SQL injection.

Therefore, to specify the parameters in the query and the expected syntax for `queryParameters` , you will need to use the specific providers' syntax:

**BigQuery**

BigQuery uses named parameters.

{% code overflow="wrap" %}

```typescript
sqlQuery: 'SELECT * FROM carto-demo-data.demo_tables.retail_stores WHERE storetype = @type AND revenue > @minRevenue'
queryParameters: { 'minRevenue': 100000, 'type': 'Supermarket' },
```

{% endcode %}

*Please note that empty arrays are not supported as parameter values.*

**Snowflake**

Snowflake supports positional parameters, such as:

{% code overflow="wrap" %}

```typescript
sqlQuery: 'SELECT * FROM demo_db.public.import_retail_stores WHERE storetype = :2 AND revenue > :1'
queryParameters: [100000, "Supermarket"],
```

{% endcode %}

**Redshift and PostgreSQL**

Snowflake supports positional parameters, such as:

{% code overflow="wrap" %}

```typescript
sqlQuery: 'SELECT * FROM carto_demo_data.demo_tables.retail_stores WHERE storetype = $2 AND revenue > $1...'
queryParameters: [100000, "Supermarket"],
```

{% endcode %}
{% endhint %}

## Response

The response of `quadbinQuerySource` is a promise that can be resolved and used in [layers](https://github.com/CartoDB/gitbook-documentation/blob/master/carto-for-developers/key-concepts/carto-for-deck.gl) and [widgets](https://docs.carto.com/carto-for-developers/reference/carto-widgets-reference).

## Connection compatibility

| Connection Data Warehouse                                                                         | Compatible           |
| ------------------------------------------------------------------------------------------------- | -------------------- |
| [BigQuery](https://docs.carto.com/carto-user-manual/connections/bigquery)                         | :white\_check\_mark: |
| [Snowflake](https://docs.carto.com/carto-user-manual/connections/snowflake)                       | :white\_check\_mark: |
| [Redshift](https://docs.carto.com/carto-user-manual/connections/redshift)                         | :white\_check\_mark: |
| [Databricks](https://docs.carto.com/carto-user-manual/connections/databricks)                     | :white\_check\_mark: |
| [Oracle](https://docs.carto.com/carto-user-manual/connections/oracle)                             | :white\_check\_mark: |
| [PostgreSQL](https://docs.carto.com/carto-user-manual/connections/postgresql)                     | :white\_check\_mark: |
| [CARTO Data Warehouse](https://docs.carto.com/carto-user-manual/connections/carto-data-warehouse) | :white\_check\_mark: |

## Layer compatibility

`quadbinQuerySource` is compatible with the following layers from the `@deck.gl/carto` module:

* [QuadbinTileLayer](https://deck.gl/docs/api-reference/carto/quadbin-tile-layer)

## Widget model compatibility

`quadbinQuerySource` is compatible with the following widget models:

* [getFormula](https://docs.carto.com/carto-for-developers/reference/carto-widgets-reference/models/getformula)
* [getCategories](https://docs.carto.com/carto-for-developers/reference/carto-widgets-reference/models/getcategories)
* [getHistogram](https://docs.carto.com/carto-for-developers/reference/carto-widgets-reference/models/gethistogram)
* [getRange](https://docs.carto.com/carto-for-developers/reference/carto-widgets-reference/models/getrange)
* [getScatter](https://docs.carto.com/carto-for-developers/reference/carto-widgets-reference/models/getscatter)
* [getTimeSeries](https://docs.carto.com/carto-for-developers/reference/carto-widgets-reference/models/gettimeseries)
* [getTable](https://docs.carto.com/carto-for-developers/reference/carto-widgets-reference/models/gettable)
