Sign in

    shiyukonghui/kingbase-client/dialect does not have a README file

    CaseFold

    pub(all) enum CaseFold {
    Lower
    Upper
    Preserve
    } derive(Eq,
    Debug
    )

    How an unquoted identifier appears in the catalog afterwards.

    ColumnKind

    pub(all) enum ColumnKind {
    BigInt
    Int32
    Int16
    Decimal(Int, Int)
    Varchar(Int)
    Char(Int)
    Timestamp
    Boolean
    }

    One SQL term a schema builder needs, mapped to a type name per mode.

    Dialect

    pub struct Dialect {
    mode : Mode
    settings : Map[String, String]
    }

    Construct it with new_dialect. The values are measured on the live instance in Client::connect, so they reflect the target, not a guess about a mode.

    Dialect::begin_statement

    fn Dialect::begin_statement(self : Dialect) -> String

    commit and rollback are accepted bare in all four modes, and the longer commit transaction / rollback transaction forms are too, so only the opening statement needs a dialect. An application that must run in every mode can send begin transaction: measured accepted by all four instances.

    Dialect::binary_copy_supported

    fn Dialect::binary_copy_supported(self : Dialect) -> Bool

    The loader still writes text: its throughput is set by the server's insert path, and text needs no encoder per column type. probe re-measures this per instance.

    Dialect::boolean_literal

    fn Dialect::boolean_literal(self : Dialect, value : Bool) -> String

    This follows the type the mode chooses, like boolean_text, but the value must be a bare literal rather than COPY field text. pg and mysql mode get a PostgreSQL boolean, whose keywords are true and false; sqlserver mode gets bit and oracle mode number(1), which take 1 and 0. The crud command in the benchmark repository measures which forms each instance accepts.

    Dialect::boolean_text

    fn Dialect::boolean_text(self : Dialect, value : Bool) -> String

    Writing 1 into a PostgreSQL boolean is accepted as true, so an old loader that sent numeric text still worked; reading it back did not match the text it had sent. Spelling the value the way the column spells it is what makes a round trip check possible.

    Dialect::case_fold

    fn Dialect::case_fold(self : Dialect) -> CaseFold

    enable_ci is read when the instance reports it. documented: case insensitive handling folds names to lower case. measured: this instance reports enable_ci = on and keeps the written case in a result column label, so label text is not evidence about the catalog.

    Dialect::catalog_view

    fn Dialect::catalog_view(self : Dialect, base : String) -> String

    measured: pg mode answers pg_class, pg_namespace, pg_indexes and rejects sys_class with 42P01; sqlserver mode answers both prefixes, so the sys_ form serves the other three modes.

    Dialect::column_type

    fn Dialect::column_type(self : Dialect, kind : ColumnKind) -> String

    The names below are the ones a schema builder needs. measured for sqlserver mode: bigint, int, smallint, numeric(18,4), varchar(n), datetime, and bit all cast without error, while varchar2, number and nvarchar2 do not exist there (SQLSTATE 42704).

    Dialect::concat

    fn Dialect::concat(self : Dialect, a : String, b : String) -> String

    documented: the MySQL reference lists CONCAT, and in MySQL || is a logical operator unless sql_mode adds PIPES_AS_CONCAT.

    Dialect::conforming_strings

    fn Dialect::conforming_strings(self : Dialect) -> Bool

    pg-compatible: the same GUC name and meaning.

    Dialect::empty_string_is_null

    fn Dialect::empty_string_is_null(self : Dialect) -> Bool

    documented: the manual for that GUC says on makes an empty string NULL to match Oracle, and that pg mode needs it off. When the GUC is absent, the mode decides.

    Dialect::extended_protocol_supported

    fn Dialect::extended_protocol_supported(self : Dialect) -> Bool

    The simple query protocol works in all four modes, so the client uses it and a false value here costs nothing.

    Dialect::flag

    fn Dialect::flag(self : Dialect, key : String, default : Bool) -> Bool

    A on / off setting, with a default for an instance that lacks it.

    Dialect::index_list_query

    fn Dialect::index_list_query(self : Dialect, table : String) -> String

    measured: sys_indexes returns the five index names of the benchmark table in sqlserver, oracle and mysql mode; pg mode has no sys_ view and answers pg_indexes instead, so the view name comes from catalog_view.

    Dialect::limit_clause

    fn Dialect::limit_clause(self : Dialect, limit : Int, offset : Int) -> String

    The modes share no one pagination syntax, so generated SQL asks for a clause instead of writing limit in the query text. measured: this sqlserver instance accepts all three of limit 1 offset 0, top 1, and offset 0 rows fetch next 1 rows only. documented: the SQL Server reference says TOP cannot combine with OFFSET and FETCH in one query, so the two forms stay separate here.

    Dialect::now_expression

    fn Dialect::now_expression(self : Dialect) -> String

    The expression that returns the current date and time in this mode. measured, one instance per mode: now() answers in all four. sysdate works only in oracle and mysql mode, and getdate() — the SQL Server form this mode is named after — is refused in all four. current_timestamp answers in all four too, and prints differently: sqlserver mode gives now() an offset (2026-10-09 12:30:55.458090+08) but current_timestamp none, mysql mode gives neither an offset, and pg mode gives both one. A client therefore reads timestamps as text and never parses them, which is what ResultSet does.

    Dialect::quote_ident

    fn Dialect::quote_ident(self : Dialect, name : String) -> String

    When quoted_identifier is off, double quotes mark a string on modes that follow SQL Server rules, so brackets are used instead. The manual does not cover bracket acceptance, so probe measures it.

    Dialect::setting

    fn Dialect::setting(self : Dialect, key : String) -> String

    The value of one setting, or "" when the instance does not report it.

    Dialect::setting_query

    fn Dialect::setting_query(key : String) -> String

    measured: select current_setting('database_mode') and show database_mode both work here.

    Dialect::sql_mode_has

    fn Dialect::sql_mode_has(self : Dialect, flag : String) -> Bool

    True when sql_mode lists one flag. measured: this instance reports sql_mode = ONLY_FULL_GROUP_BY,ANSI_QUOTES even in sqlserver mode.

    Dialect::timestamp_text_example

    fn Dialect::timestamp_text_example(self : Dialect) -> String

    documented: Oracle mode formats date text from nls_date_format, which this instance does not expose.

    Dialect::timestamp_type

    fn Dialect::timestamp_type(self : Dialect) -> String

    The type name this mode uses for a date-and-time column.

    Dialect::top_clause

    fn Dialect::top_clause(self : Dialect, n : Int) -> String

    documented: TOP belongs to the SQL Server grammar. The other modes return "" here, and the caller uses limit_clause with offset 0 instead.

    Dialect::wide_sum

    fn Dialect::wide_sum(self : Dialect, column : String) -> String

    An aggregate checksum taken in one mode therefore does not equal the same checksum taken in another, which matters when a benchmark result is compared across instances.

    Mode

    pub(all) enum Mode {
    Pg
    Oracle
    Mysql
    Sqlserver
    } derive(Eq,
    Debug
    )

    against a server. Verify with kingbase_bench probe before you rely on it.

    Mode::name

    fn Mode::name(self : Mode) -> String

    The short name the server uses for this mode.

    mode_of

    fn mode_of(name : String) -> Mode?

    The GUC also reports 0 to 3, so both spellings are accepted.

    new_dialect

    fn new_dialect(rows : Array[(String, String)], fallback : Mode) -> Dialect

    Reads the settings a Dialect needs from rows of (name, value).

    setting_names

    fn setting_names() -> Array[String]

    One query asks for all of them. sqlserver mode treats a double quote as a string delimiter unless quoted_identifier is on, and an apostrophe as an escape, so a name list built with string concatenation can fail to parse on one mode and work on another. The query is therefore written once, as the bracket-quoted form in sql_in_list, and this list only names the keys. measured in docs/data/probe-sqlserver.txt.

    settings_views

    fn settings_views(mode : Mode) -> Array[String]

    measured across all four modes: pg mode has no sys_* view at all (sys_settings answers 42P01) and exposes pg_settings; sqlserver, oracle and mysql answer sys_settings. The second name is a fallback for a build that reports its mode differently from the catalogs it ships.

    sql_in_list

    fn sql_in_list(view : String) -> String

    The names are single-quoted, which is the form every mode takes; the view name is the caller's choice, because it differs per mode. On another mode the query may fail to parse, and Client::connect then falls back to show per name, so a mode with no such view still gets its dialect.

    sql_literal

    fn sql_literal(value : String) -> String

    An apostrophe inside the value is doubled, which is the standard escape and needs no backslash, so the literal is safe whatever standard_conforming_strings says.

    unknown_mode

    fn unknown_mode() -> Mode

    pg is the base every KingbaseES build keeps, because KingbaseES is built on the PostgreSQL kernel, so an unreadable mode is closest to that.

    Source Files