stratified_packager.toolbelt.sql

Plugin-agnostic SQL string building for the SQLite/GeoPackage dialect.

Pure standard library: this module imports neither qgis nor osgeo (GDAL/OGR), so its helpers stay usable from background threads, scripts/ and osgeo-free tests. It owns the SQL text concerns — identifier quoting and reserved-table-name guarding — while gpkg owns the OGR and sqlite3 work that consumes the quoting.

Functions

equality_operands(query, /)

Collect the identifiers an SQL query compares with =, table qualifier dropped.

quote_identifier(name, /)

Quote an SQL identifier (table or column name) with double quotes.

safe_table_name(name, /)

Prefix _ to dodge GeoPackage/SQLite reserved table-name prefixes.

source_tables(query, /)

Collect the table names an SQL query reads (FROM / JOIN), quoting stripped.

sqlite_where_error(columns, where, /)

Report why SQLite could not compile where as a WHERE clause over columns.

stratified_packager.toolbelt.sql.equality_operands(query, /)[source]

Collect the identifiers an SQL query compares with =, table qualifier dropped.

Answers “which columns could an index serve here?” for a caller that intersects the result with a table’s real column names. That intersection is what lets this stay a scan rather than a parser: an operand that is a literal, a function name or a table alias has no matching column and drops out, so over-matching costs nothing.

Parameters:

query (str) – SQL text, in any dialect.

Return type:

frozenset[str]

Returns:

The identifiers on both sides of every = whose two operands are bare words.

stratified_packager.toolbelt.sql.quote_identifier(name, /)[source]

Quote an SQL identifier (table or column name) with double quotes.

Parameters:

name (str) – The raw identifier.

Return type:

str

Returns:

The double-quoted identifier with embedded quotes doubled.

stratified_packager.toolbelt.sql.safe_table_name(name, /)[source]

Prefix _ to dodge GeoPackage/SQLite reserved table-name prefixes.

OGR refuses to create a GeoPackage layer whose name begins with gpkg, and SQLite reserves the sqlite_ prefix for its own tables. A name that begins with either (case-insensitively, since both dialects fold table-name case) gets a leading _; every other name is returned unchanged. Idempotent: _gpkg… no longer matches.

Parameters:

name (str) – A candidate (already-sanitized) table name.

Return type:

str

Returns:

The name, with a leading _ when it would otherwise be reserved.

stratified_packager.toolbelt.sql.source_tables(query, /)[source]

Collect the table names an SQL query reads (FROM / JOIN), quoting stripped.

Answers “which tables does this query expect to exist?” for a caller that checks them against the tables it is about to create.

Parameters:

query (str) – SQL text, in any dialect.

Return type:

frozenset[str]

Returns:

The table names, as written (case is preserved; both SQLite and GeoPackage fold it, so a caller comparing against real table names should fold too).

stratified_packager.toolbelt.sql.sqlite_where_error(columns, where, /)[source]

Report why SQLite could not compile where as a WHERE clause over columns.

A filter written for another provider’s dialect (a PostgreSQL :: cast, a schema-qualified table, a function SQLite lacks) is accepted by the layer API yet fails when the SQLite/GeoPackage backend prepares the statement — where the failure surfaces as a bare CPLError rather than a caller-visible one. Compiling it here answers the same question up front.

The statement is compiled with EXPLAIN, which resolves every table, column and function name without executing anything. Compilation runs against a throwaway in-memory table, so no GeoPackage is touched and the caller needs only the column names. Extension functions a real GeoPackage connection would register (SpatiaLite’s, GDAL’s) are absent here, so treat a complaint as advisory rather than proof the filter is unusable.

Parameters:
  • columns (Iterable[str]) – The column names the clause may reference.

  • where (str) – The candidate WHERE clause (no leading keyword).

Return type:

str | None

Returns:

SQLite’s message, or None when the clause compiles.

stratified_packager.toolbelt.sql._EQUALITY_OPERAND: Final = re.compile('(?:\\w+\\s*\\.\\s*)?(\\w+)\\s*=\\s*(?:\\w+\\s*\\.\\s*)?(\\w+)')

Both operands of an = comparison, with any table./alias. qualifier dropped.

A word character never precedes the = of <=, >=, != or <>, so none of those operators can match.

stratified_packager.toolbelt.sql._RESERVED_TABLE_PREFIXES: Final = ('gpkg', 'sqlite_')

Reserved table-name prefixes: OGR rejects gpkg; SQLite reserves sqlite_.

stratified_packager.toolbelt.sql._SOURCE_TABLE: Final = re.compile('\\b(?:from|join)\\s+                  # the keyword introducing a table reference\n        (?:"([^"]+)"                        # "quoted"\n          |`([^`]+)`                        # `backquoted`\n, re.IGNORECASE|re.VERBOSE)

The table name following each FROM / JOIN, in whichever way it is spelled.