mirror of
https://github.com/apache/superset.git
synced 2026-09-01 21:11:28 +00:00
checkfirst=False only sidestepped create_all()'s own call to has_table(); Inspector.get_columns() (used by OceanBaseEngineSpec.get_columns(), which the second test needs to actually exercise) calls the same broken has_table() internally and hit the identical ObjectNotExecutableError (confirmed on real CI). Every other raw-SQL method in the same dialect module correctly uses connection.exec_driver_sql(...) -- this looks like an isolated oversight in just has_table(), not a deliberate design choice, so this monkeypatches it to do the same thing the rest of the dialect already does, fixing the root cause for both call sites instead of routing around one of them.
69 lines
2.9 KiB
Python
69 lines
2.9 KiB
Python
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
"""
|
|
Shared body for the "paginated query returns correct rows in order" test
|
|
that db_engine_specs.{cockroachdb,crate,db2,mssql,oracle,trino}'s
|
|
testcontainers suites each run against their own real instance: a plain
|
|
SQLAlchemy Core LIMIT/OFFSET query, compiled and executed for real. Mocked
|
|
tests cannot catch a dialect compiling this incorrectly (see
|
|
apache/superset#42899, where Trino emitted OFFSET before LIMIT) -- only
|
|
real execution can.
|
|
|
|
Each call site keeps its own test function (and dialect-specific docstring)
|
|
so failures still report against the right module; this only factors out
|
|
the identical table setup/assert body, via an optional post-insert hook for
|
|
dialects (CrateDB) that need one, and an optional extra-table-args hook for
|
|
dialects (ClickHouse) whose CREATE TABLE requires a schema item a plain
|
|
Column/primary key can't express.
|
|
"""
|
|
|
|
from collections.abc import Callable
|
|
from typing import Any
|
|
|
|
from sqlalchemy import Column, insert, Integer, MetaData, select, Table as SATable
|
|
from sqlalchemy.engine import Connection, Engine
|
|
|
|
|
|
def assert_paginated_query_returns_correct_rows_in_order(
|
|
engine: Engine,
|
|
after_insert: Callable[[Connection], None] | None = None,
|
|
extra_table_args: tuple[Any, ...] = (),
|
|
) -> None:
|
|
metadata = MetaData()
|
|
t = SATable(
|
|
"pilot_pagination",
|
|
metadata,
|
|
# autoincrement=False: a single-column integer primary key otherwise
|
|
# implicitly becomes AUTO_INCREMENT on MySQL/MariaDB. That column
|
|
# type treats an explicit 0 as NULL by default (NO_AUTO_VALUE_ON_ZERO
|
|
# is off), so the id=0 row below would silently get auto-assigned 1,
|
|
# colliding with the explicit id=1 row in the same batch insert.
|
|
Column("id", Integer, primary_key=True, autoincrement=False),
|
|
*extra_table_args,
|
|
)
|
|
metadata.create_all(engine)
|
|
with engine.begin() as conn:
|
|
conn.execute(insert(t), [{"id": i} for i in range(10)])
|
|
if after_insert is not None:
|
|
after_insert(conn)
|
|
|
|
with engine.connect() as conn:
|
|
stmt = select(t.c.id).order_by(t.c.id).limit(3).offset(4)
|
|
rows = conn.execute(stmt).fetchall()
|
|
|
|
assert [row.id for row in rows] == [4, 5, 6]
|