Member Junction
    Preparing search index...

    SQL Server implementation of the CodeGen database provider. Generates SQL Server-native DDL for views, stored procedures, triggers, indexes, full-text search, permissions, and other database objects.

    Registered with MJGlobal.ClassFactory against the canonical 'sqlserver' platform key — SQLCodeGenBase resolves this provider via ClassFactory.CreateInstance(CodeGenDatabaseProvider, configInfo.dbPlatform). Downstream packages can subclass and re-register with higher priority to override codegen behavior — same extension hook every other MJ class uses.

    Hierarchy (View Summary)

    Index

    Constructors

    Accessors

    Methods

    addColumnSQL addDefaultConstraintSQL alterColumnTypeAndNullabilitySQL buildExecParamForField buildPrimaryKeyComponents callRoutineSQL canSelfJoinViewForVirtualNameField columnToken compareDataTypes conditionalInsertSQL dropDefaultConstraintSQL dropObjectSQL executeEntityPhased? executeSQLFileViaShell foreignKeyIndexName formatDefaultValue formatIndexStatement formatInsertDefaultValue generateAllEntitiesSQLFileHeader generateBaseView generateCRUDCreate generateCRUDDelete generateCRUDParamString generateCRUDPermissions generateCRUDUpdate generateDropGuard generateForeignKeyIndexes generateFullTextSearch generateFullTextSearchPermissions generateInsertFieldString generateRootFieldJoin generateRootFieldSelect generateRootIDFunction generateSingleCascadeOperation generateSQLFileHeader generateTimestampColumns generateTimestampTrigger generateUpdateFieldString generateViewPermissions generateViewRefreshSQL generateViewTestQuerySQL getCheckConstraintsSchemaFilter getCompositeUniqueConstraintCheckSQL getCRUDRoutineName getEntitiesWithMissingBaseTablesFilter getFixVirtualFieldNullabilitySQL getForeignKeyIndexExistsSQL getMetadataSupportObjectsSQL getPendingEntityFieldsSQL getPrimaryKeyIndexNameSQL getRoutineNamesBySchemaSQL getSystemSchemasToExclude getViewColumnsSQL getViewDefinitionSQL getViewExistsSQL indexPrefix isIndexableForeignKey isParamRequired maxIdentifierLength needsClearCompanion parseColumnDefaultValue quoteSQLForExecution regenerateBaseView? renderParameterType SetupDataSource shouldIncludeFieldInParams tableToken validateExpectedCRUDFunctions wrapInsertWithConflictGuard

    Constructors

    Accessors

    • get BatchSeparator(): string

      Returns the batch separator for the database platform. SQL Server: 'GO' PostgreSQL: '' (empty string, uses semicolons)

      Returns string

    Methods

    • Generates ALTER TABLE ... ADD COLUMN SQL. SQL Server: ALTER TABLE [schema].[table] ADD colName TYPE [NOT] NULL [DEFAULT expr] PostgreSQL: ALTER TABLE schema."table" ADD COLUMN "colName" TYPE [NOT] NULL [DEFAULT expr]

      Parameters

      • schema: string
      • tableName: string
      • columnName: string
      • dataType: string
      • nullable: boolean
      • OptionaldefaultExpression: string

      Returns string

    • Generates ALTER TABLE ... ALTER COLUMN to change type and nullability. SQL Server: ALTER TABLE ... ALTER COLUMN col TYPE NULL|NOT NULL PostgreSQL: ALTER TABLE ... ALTER COLUMN "col" TYPE type, ALTER COLUMN "col" SET|DROP NOT NULL

      Parameters

      • schema: string
      • tableName: string
      • columnName: string
      • dataType: string
      • nullable: boolean

      Returns string

    • Builds the EXEC parameter fragment(s) for a single field when calling a tolerant update SP. Returns an array of @ParamName = value strings.

      For most fields this is just ['@FieldName = @variable']. But when clearValue is true and the field has a _Clear companion (see needsClearCompanion), an additional @FieldName_Clear = 1 is prepended so the tolerant SP actually sets the column to NULL instead of treating the NULL parameter as "leave unchanged".

      This is the single source of truth for the calling convention of tolerant update SPs. All codepaths that generate EXEC calls to spUpdate — cascade-update cursors, future SP-to-SP calls, etc. — should use this method to stay in sync with the SP declaration logic in generateCRUDParamString.

      Parameters

      • ef: EntityFieldInfo

        The entity field being passed

      • valueExpr: string

        The SQL expression for the value (e.g. @prefixed_var)

      • clearValue: boolean = false

        Whether this field is being explicitly set to NULL

      Returns string[]

    • Builds the four SQL fragments needed to work with an entity's primary key columns in cursor-based cascade operations:

      • varDeclarations: @{prefix}{PK} TYPE variable declarations for DECLARE.
      • selectFields: Bracketed column names for the cursor SELECT.
      • fetchInto: @{prefix}{PK} variable references for FETCH INTO.
      • routineParams: Named parameter assignments (@PK = @{prefix}{PK}) for EXEC.

      Supports composite primary keys by iterating all PK fields. The optional prefix defaults to 'Related' to avoid variable name collisions in nested cursor blocks.

      Parameters

      Returns {
          fetchInto: string;
          routineParams: string;
          selectFields: string;
          varDeclarations: string;
      }

    • Builds a SQL Server EXEC statement for invoking a stored procedure. When paramNames are provided, generates named parameter syntax (@ParamName=value); otherwise uses positional parameter values. Returns just EXEC [schema].[routine] if no params.

      Parameters

      • schema: string
      • routineName: string
      • params: string[]
      • OptionalparamNames: string[]

      Returns string

    • Whether this dialect can handle a base view that LEFT-JOINs itself to read a virtual computed column (e.g. vwRecordChanges joining to itself for the RestoredFromID virtual NameField lookup).

      Default: false. No shipped provider currently supports this pattern:

      • PostgreSQL: CREATE OR REPLACE VIEW resolves view names against catalog state at parse time, so a self-reference fails with 42P01 undefined_table. A CREATE OR REPLACE retry against a NULL-typed stub then fails with cannot change data type of view column ... from text to character varying(N) because PG enforces strict column-type compat.
      • SQL Server: the base view emitter uses DROP VIEW then CREATE VIEW, and SQL Server resolves view-body references at parse/bind time — there is no deferred name resolution for view bodies the way there is for stored procedures. After the DROP, the post-DROP self-reference fails with error 208 "Invalid object name".

      With the default of false, sql_codegen.ts skips the self-virtual- NameField join entirely for self-FK + virtual-NameField cases. The trade- off: the corresponding virtual lookup column (e.g. RestoredFrom on vwRecordChanges, or Parent on a vwTags-style view if the Name Field were computed) is not emitted on the base view. Matches the baseline- shipped view shapes.

      Subclasses can override to return true if a future dialect (or a provider that switches to a different emit pattern, e.g. stub-then-alter) can support the self-reference. The fix for the underlying conflation between SQL Server computed columns and view-only columns under IsVirtual = 1 would let the join target the base table instead, removing the need for this capability flag entirely.

      Returns boolean

    • Generates SQL to dynamically find and drop the default constraint on a column. Unlike PostgreSQL's simple ALTER COLUMN DROP DEFAULT, SQL Server requires looking up the constraint name from sys.default_constraints joined through sys.tables, sys.schemas, and sys.columns, then executing a dynamic ALTER TABLE DROP CONSTRAINT via EXEC(). The generated SQL is safe to run even if no default constraint exists (guarded by IF @constraintName IS NOT NULL).

      Parameters

      • schema: string
      • tableName: string
      • columnName: string

      Returns string

    • Generates a DROP statement for a database object (view/procedure/function). SQL Server: IF OBJECT_ID('...', 'P') IS NOT NULL DROP PROCEDURE ... PostgreSQL: DROP FUNCTION IF EXISTS ... CASCADE

      Note: This differs from generateDropGuard() which is used for CREATE OR REPLACE patterns. This method is used for cleanup operations.

      Parameters

      • objectType: "VIEW" | "PROCEDURE" | "FUNCTION"
      • schema: string
      • name: string

      Returns string

    • Optional — dialect-specific phased execution of a single entity's full CodeGen SQL package (view, CRUD functions, permissions) for the main per-entity run path.

      Default path concatenates all the SQL and hands it to the shell executor, which runs it as a single multi-statement query. When any statement fails, pg's simple-query protocol aborts the rest of the batch — so a view that fails 42P16 silently blocks the CREATE FUNCTIONs that follow for the same entity.

      Providers that implement this method run the pieces in separate phases so a failure in phase 1 prevents phase 2 from producing functions that reference a missing or stale view. PG's implementation additionally routes the view phase through the 42P16 capture/restore fallback.

      Phasing contract: Phase 0 = TVF DDL (tvfSQL) — root-ID functions for recursive FKs that the base view references. Must run before phase 1 or PG rejects the view with function does not exist. Phase 1 = view DDL (viewSQL) — may invoke provider-specific recovery. Phase 2 = CRUD function DDL — ONLY runs if phase 1 succeeded. Phase 3 = view permissions (viewPermSQL) — runs only if phase 2 succeeded. The success/phase pair in the result identifies exactly where things fell over so the caller doesn't have to bisect.

      Parameters

      • opts: {
            crudCreateSQL: string;
            crudDeleteSQL: string;
            crudUpdateSQL: string;
            entity: EntityInfo;
            tvfSQL: string;
            viewPermSQL: string;
            viewSQL: string;
            willRegenerate?: Set<string>;
        }
        • crudCreateSQL: string
        • crudDeleteSQL: string
        • crudUpdateSQL: string
        • entity: EntityInfo
        • tvfSQL: string

          Root-ID TVF DDL emitted ahead of the view. Empty when the entity has no recursive ParentID FKs.

        • viewPermSQL: string
        • viewSQL: string
        • OptionalwillRegenerate?: Set<string>

      Returns Promise<PhasedExecutionResult>

    • Executes a SQL file against SQL Server using the sqlcmd command-line utility. Reads connection details (server, port, instance, user, password, database) from the shared sqlConfig object. On Windows, converts file paths containing spaces to 8.3 short format to avoid quoting issues with sqlcmd. Spawns the process with QUOTED_IDENTIFIER enabled (-I) and severity threshold 17 (-V 17). Optionally adds -C for trustServerCertificate. Returns true on successful execution, false on failure.

      Parameters

      • filePath: string

      Returns Promise<boolean>

    • Composes the automatic foreign-key index name and enforces the dialect's identifier length limit. Dialect-independent in shape — {prefix}{table}_{column} — while the casing of the prefix, the table/column token spelling, and the length cap come from the dialect hooks.

      NOTE: the resulting names are deliberately NOT unified across dialects. SQL Server names from BaseTableCodeName/CodeName, PostgreSQL from snake-cased BaseTable/Name. Changing either would orphan every existing index in deployed databases (CodeGen would create new ones alongside the old), so the token hooks preserve each dialect's historical spelling exactly.

      Parameters

      Returns string

    • Formats a raw default value string for embedding in generated SQL. Recognizes common SQL Server functions (NEWID(), NEWSEQUENTIALID(), GETDATE(), GETUTCDATE(), SYSDATETIME(), SYSDATETIMEOFFSET(), CURRENT_TIMESTAMP, USER_NAME(), SUSER_NAME(), SYSTEM_USER) and strips wrapping parentheses from them. For literal values, strips surrounding single quotes and re-applies them only if needsQuotes is true. Returns 'NULL' for empty or whitespace-only inputs.

      Parameters

      • defaultValue: string
      • needsQuotes: boolean

      Returns string

    • Render hook: returns the default value for a field formatted for embedding in a generated INSERT statement. The base implementation delegates to formatDefaultValue (which handles SQL functions, quoted literals, etc.). Dialects with type-strict semantics may need to massage the value further — for example, PostgreSQL maps SQL Server BIT literal defaults (0/1) to PG BOOLEAN literals (FALSE/TRUE) so that COALESCE(boolean_param, 0) doesn't fail with a type-mismatch error.

      Parameters

      Returns string

    • Generates the spCreate stored procedure for a SQL Server entity. Handles three primary key strategies:

      1. Auto-increment: Uses SCOPE_IDENTITY() to retrieve the generated key.
      2. UNIQUEIDENTIFIER with default (e.g., NEWSEQUENTIALID()): Uses an OUTPUT clause into a table variable with a two-branch IF @PK IS NOT NULL pattern so callers can optionally supply their own GUID or let the database default apply.
      3. UNIQUEIDENTIFIER without default: Falls back to ISNULL(@PK, NEWID()).
      4. Composite / other PKs: Constructs a multi-column WHERE clause for retrieval.

      The procedure always returns the newly created record via the entity's base view. Includes GRANT EXECUTE permissions for authorized roles.

      Parameters

      Returns string

    • Generates the parameter list string for a CRUD routine with tolerant SP signatures (Pillar 1 of the cross-app migration architecture).

      Structural logic — what's required, what's optional, when a _Clear companion appears — lives here in the base class and is shared across dialects. The dialect-specific syntax (parameter prefix, default keyword, type rendering) is delegated to:

      • Dialect.ParameterRef(name)@Name vs. p_name
      • Dialect.ParameterDefault(value) = NULL vs. DEFAULT NULL
      • Dialect.NullLiteralNULL literal
      • renderParameterType(ef) — type formatting (T-SQL native vs. PG-mapped)

      Subclasses can override the hooks above without re-implementing the full method. Subclasses can also override the method itself if their dialect imposes additional constraints not modelable through hooks (e.g. PostgreSQL's "all params after the first DEFAULT must also have DEFAULTs" rule, which the PostgreSQL provider handles via override).

      Parameters

      Returns string

    • Generates the spUpdate stored procedure for a SQL Server entity. Performs a standard UPDATE ... SET ... WHERE PK = @PK and uses @@ROWCOUNT to detect whether the row was found: if no rows were updated (e.g., stale PK or concurrent delete), returns an empty result set with the base view's column structure (SELECT TOP 0 ... WHERE 1=0); otherwise returns the updated record from the base view. Also generates the __mj_UpdatedAt timestamp trigger if the entity has that column.

      Parameters

      Returns string

    • Generates SQL Server-style conditional DROP guards using the IF OBJECT_ID(...) IS NOT NULL pattern. Maps each object type to its SQL Server type code: 'V' for views, 'P' for procedures, 'IF' for inline table-valued functions, and 'TR' for triggers. Each guard is terminated with a GO batch separator.

      Parameters

      • objectType: "VIEW" | "PROCEDURE" | "FUNCTION" | "TRIGGER"
      • schema: string
      • name: string

      Returns string

    • Generates SQL Server full-text search infrastructure for an entity, conditionally producing up to three components based on entity metadata flags:

      1. Full-text catalog (FullTextCatalogGenerated): CREATE FULLTEXT CATALOG if one doesn't already exist, defaulting to MJ_FullTextCatalog.
      2. Full-text index (FullTextIndexGenerated): Drops any existing FT index on the table, then creates a new one covering the specified search fields with English language.
      3. Search function (FullTextSearchFunctionGenerated): An inline table-valued function that wraps CONTAINS() to return matching primary key values.

      Parameters

      Returns FullTextSearchResult

      The generated SQL and the resolved function name for permission grants.

    • Generates the column-list or value-list portion of an INSERT statement, depending on whether prefix is empty (column names) or non-empty (parameter values).

      Empty prefix — produces dialect-quoted column names suitable for the INSERT INTO ... (col1, col2) clause.

      Non-empty prefix — produces the parameter-value list suitable for the VALUES (...) clause, with tolerant-SP behavior:

      • Special-date fields are substituted with the dialect's CurrentTimestampUTC() (created/updated) or NullLiteral (deleted-at).
      • GUID fields with database defaults emit a CASE that detects the empty-GUID sentinel and falls back to the database default; otherwise wraps with IsNull.
      • Non-nullable fields with defaults are wrapped in IsNull(@Param, default).
      • Nullable fields with non-NULL defaults emit a _Clear companion CASE so callers can distinguish "leave default" from "explicitly NULL."
      • Plain nullable fields with no default pass the parameter reference through directly (NULL flows through).

      Skips auto-increment, virtual, and non-updatable fields. The PK column can be optionally excluded (used by the two-branch GUID-PK insert pattern in generateCRUDCreate).

      Dialect-specific syntax is fully delegated to:

      • Dialect.QuoteIdentifier, Dialect.ParameterRef,
      • Dialect.IsNull, Dialect.NullLiteral,
      • Dialect.CurrentTimestampUTC, Dialect.EmptyUUIDLiteral,
      • formatInsertDefaultValue(ef) render hook (for type-strict dialects that need to massage default values).

      Parameters

      Returns string

    • Parameters

      • schema: string
      • tableName: string

      Returns string

      Currently unused in production — timestamp columns are added individually via ensureSpecialDateFieldExistsAndHasCorrectDefaultValue() → addColumnSQL(). This method exists to satisfy the abstract contract. Uses the same defensive multi-step pattern as addColumnSQL() to remain safe if ever called on tables with existing rows on SQL Azure.

    • Generates the SET clause body for an UPDATE statement with tolerant merge semantics. Each non-PK column wraps the parameter with the dialect's null-coalescing call against the column's existing value (SET [Col] = ISNULL(@Param, [Col]) on SQL Server, SET "col" = COALESCE(p_col, "col") on PostgreSQL) so omitting a parameter preserves the existing row value. Nullable columns whose database default is non-NULL also emit a _Clear companion branch that lets callers distinguish "leave unchanged" from "explicitly NULL."

      The full structural logic lives here in the base class; only the per-line render is dialect-specific and that's resolved through the Dialect accessor's helpers (QuoteIdentifier, ParameterRef, IsNull, NullLiteral). Subclasses can override to customize line formatting if a future dialect needs something different.

      Parameters

      Returns string

    • Returns a SQL query that checks whether a column participates in a composite (multi-column) unique constraint. Queries sys.indexes, sys.index_columns, and sys.columns to find non-primary-key unique indexes that include the specified column AND have more than one column. Returns rows if the column is part of such a constraint; the orchestrator checks recordset.length > 0.

      Parameters

      • schema: string
      • tableName: string
      • columnName: string

      Returns string

    • Returns DDL that creates/replaces the platform's metadata-management support objects (introspection views and the routines manage-metadata invokes via callRoutineSQL), or null when the platform ships them through migrations instead.

      These objects are CodeGen's own machinery — only CodeGen calls them — so platforms that return DDL here get it executed (idempotently) at the start of every manageMetadata run. That guarantees the objects can never be missing or version-skewed relative to the CodeGenLib code that calls them.

      SQL Server: returns null (objects ship in the baseline migrations). PostgreSQL: returns the full support-object DDL.

      Parameters

      • _mjCoreSchema: string

      Returns string | null

    • Generates the full SQL query to retrieve entity fields that exist in the database schema but are not yet registered in MJ metadata. The query is assembled from three parts:

      1. Temp table materialization: Copies vwForeignKeys, vwTablePrimaryKeys, and vwTableUniqueKeys into temp tables so SQL Server can build real statistics instead of expanding nested view-on-view joins with bad cardinality estimates.
      2. Main CTE query: Uses MaxSequences CTE to calculate proper field ordering and NumberedRows CTE to deduplicate results, joining against the temp tables for FK, PK, and unique key detection.
      3. Cleanup: Drops the temp tables.

      Parameters

      • mjCoreSchema: string
      • OptionalentityIDs: string[]

      Returns string

    • Returns a SQL query that lists every stored procedure / function name in the given schemas. Used by the post-run CRUD validator to diff expected vs actual routine presence in one round trip.

      The result set must contain exactly two columns: schema_name — the schema the routine lives in routine_name — the proc/function name as stored in the catalog

      SQL Server: queries sys.objects for procedures and functions. PostgreSQL: queries pg_proc joined to pg_namespace.

      Default: returns empty string. Providers that don't implement this opt out of the post-run CRUD validator (the validator returns no missing when this returns empty), preserving backwards compatibility for downstream subclasses that haven't been updated.

      Parameters

      • _schemas: string[]

      Returns string

    • Decides whether a field should get an automatic foreign-key index. Dialect-independent.

      A field qualifies when it points at another entity and is a real, materialized column:

      • RelatedEntityID — the field is a foreign key. This is the base-table column that actually stores the relationship. (The sibling RelatedEntity field is a view join on that ID, not a base column; the two never disagree in practice — verified 0/793 divergence across the FK fields in the reference database — so keying off the ID is both equivalent and more direct.)
      • !IsPrimaryKey — a primary key is already covered by its own index. In 1:1 extension-table patterns the child's PK is also an FK to the parent, and indexing it again would be pure overhead.
      • !IsVirtual — virtual fields have no underlying column, so CREATE INDEX on one would reference a column that does not exist.

      The PK/virtual exclusions previously existed only on the PostgreSQL side; hoisting them here applies them to every dialect by construction. Current real-world exposure is zero (no FK field in the reference database is also a primary key or virtual), so this is a guard against a future case rather than a change in today's generated output.

      Parameters

      Returns boolean

    • Tolerant-SP semantics: returns true when this parameter must be provided by every caller (no default, no fallback). Pure decision logic — Pillar 1 of the cross-app migration architecture.

      • PKs: required on update, optional on non-AutoIncrement create (codegen emits a default that lets the database supply the value).
      • Non-PK on update: never required (merge semantics).
      • Non-PK on create: required only when the column is NOT NULL with no database default — i.e. a value the DB has no way to fill in.

      Parameters

      Returns boolean

    • Returns true when codegen should emit a <Param>_Clear companion parameter for the given field. The companion lets callers disambiguate "leave unchanged / apply DB default" (omit the parameter) from "explicitly set this column to NULL" (<Param>_Clear = 1). Required only for nullable columns whose database default is itself non-NULL — without the companion, a caller could not preserve a literal NULL because the dialect's IsNull wrap would always substitute the default.

      Routes the NULL-literal check through the dialect so future dialects can override what "this value is NULL" looks like in their generated SQL. Pure decision logic — no rendering.

      Parameters

      Returns boolean

    • Parses a raw SQL Server column default value from the system catalog into a clean form. SQL Server wraps defaults in parentheses (e.g., (getdate()), ((1)), (N'foo')), so this method applies three successive stripping passes:

      1. Strips one layer of wrapping parentheses.
      2. Strips the N'...' Unicode string prefix.
      3. Strips surrounding single quotes from plain string literals.

      Returns null if the input is null or undefined.

      Parameters

      • sqlDefaultValue: string

      Returns string | null

    • Optional — dialect-specific fast path for regenerating a single entity's base view with recovery logic.

      When provided, the orchestration layer (sql.ts regenerateFailedBaseViews) will route regeneration through this method instead of the generic write-temp-file-and-shell-out path. Implementations can add capture/ recovery behavior around the CREATE OR REPLACE VIEW — e.g. PG's 42P16 capture-and-restore fallback that preserves dependent views, functions, grants, comments, and ownership across the unavoidable DROP CASCADE.

      Parameters

      • entity: EntityInfo

        The entity whose base view is being regenerated.

      • viewSQL: string

        The full output of generateBaseView for this entity.

      • OptionalwillRegenerate: Set<string>

        Optional set of "schema.viewName" strings for views the caller will regenerate later in the same run — implementations may skip restoring those dependents since CodeGen will recreate them.

      Returns Promise<void>

      Error on failure — callers should treat this identically to any other per-entity regeneration failure (collected into the batch summary, halts the install in strict mode).

    • Cross-checks the entity-level AllowAPI/spGenerated/sp* configuration against the routines actually present in the database after CodeGen finishes. Returns one entry per missing routine.

      Why this exists: silent generation gaps (e.g. an entity dropped because an upstream batch errored, or stale entity-field metadata causing the PK check to fail) historically reported success at the pipeline level while leaving runtime CRUD broken. This validator turns that into a loud, actionable failure list before the install pipeline exits.

      What's expected per entity:

      • Skip virtual entities (no DB-backed routines).
      • For each of Create / Update / Delete:
        • Skip when the corresponding Allow{Type}API flag is false.
        • Look up the routine name via getCRUDRoutineName (which honors entity.spCreate/spUpdate/spDelete overrides; otherwise returns the dialect-generated default).
        • Report it as missing when not found in the DB catalog.

      Schema-level case sensitivity: SQL Server is case-insensitive, PostgreSQL is case-preserving. Both lookups normalize via lowercase to keep the validator dialect-agnostic.

      Default implementation works for both dialects via the getRoutineNamesBySchemaSQL helper. Providers may override to add platform-specific shortcuts (e.g. checking only sys.procedures on SQL Server) but the default is fine for all current dialects.

      Parameters

      Returns Promise<CRUDValidationMissing[]>

    • Wraps an INSERT statement with a conditional existence check at the statement level. SQL Server: Adds IF NOT EXISTS (...) BEGIN prefix and END suffix. PostgreSQL: Adds ON CONFLICT DO NOTHING suffix (no prefix needed).

      Parameters

      • conflictCheckSQL: string

        The SQL Server existence check query. Ignored on PostgreSQL.

      Returns { prefix: string; suffix: string }

      An object with prefix and suffix strings to wrap around the INSERT.