Class Catalog

java.lang.Object
dev.frostlake.metastore.Catalog

public class Catalog extends Object
  • Constructor Details

    • Catalog

      public Catalog()
  • Method Details

    • createDatabase

      public void createDatabase(String name)
    • cloneDatabase

      public void cloneDatabase(String sourceName, String targetName)
    • dropDatabase

      public void dropDatabase(String name, boolean cascade)
    • dropSchema

      public void dropSchema(String databaseName, String schemaName, boolean cascade)
      Drop a schema and move the session off it when it was the current one.

      ★ THE SCHEMA FALLS BACK TO PUBLIC, not to nothing — live leaves the DATABASE alone and puts the schema back to PUBLIC, which is the same landing place useDatabase(java.lang.String) chooses. Only dropping the database itself clears both.

      Parameters:
      databaseName - the schema's database
      schemaName - the schema to drop
      cascade - whether to drop the schema's contents with it
    • getDatabase

      public Database getDatabase(String name)
      A database by name, matched ignoring case — the INTERNAL Java API, used by engine plumbing and by tests that name test_db in lower case. SQL resolution must not come through here; see databaseExact(java.lang.String).
    • databaseExact

      public Database databaseExact(String name)
      The database a SQL reference names, matched EXACTLY.

      A reference resolves to a name first — bare folds to upper, quoted keeps its case — and that name must then equal a stored one. Live rejects mixedDb for a database created as "mixedDb" with Database 'MIXEDDB' does not exist or not authorized., naming the resolved form rather than the spelling; so does this.

    • isPolicyInUse

      public boolean isPolicyInUse(String policyName, boolean masking)
      True when a masking policy (masking) or row access policy is attached to any column, table or view — Snowflake refuses to drop or replace such a policy (live-verified). Attachment names may be stored bare or qualified, so the comparison uses the last segment.
    • getAllDatabases

      public List<Database> getAllDatabases()
    • beginSessionScope

      public void beginSessionScope(String database, String schema)
      Begin a per-thread session scope: until clearSessionScope() runs on this thread, the current database/schema are read from and written to this scope only. The concurrent front-end brackets every statement with begin/clear so sessions cannot see each other's context.
    • clearSessionScope

      public void clearSessionScope()
      End this thread's session scope (idempotent). Read the final values via the getters first.
    • currentSessionScope

      public String[] currentSessionScope()
      This thread's active scope (or null) — capture before nesting another scope on the same thread.
    • restoreSessionScope

      public void restoreSessionScope(String[] scope)
      Reinstate a scope captured by currentSessionScope() (null clears), unwinding a nested scope.
    • useDatabase

      public void useDatabase(String name)
    • restoreContext

      public void restoreContext(String databaseName, String schemaName)
      Restore a previously-saved (database, schema) pair WITHOUT re-validating it — for unwinding a CALL or a task back to the caller's context. Re-running useDatabase(java.lang.String)/useSchema(java.lang.String) there can throw (the objects may have been dropped meanwhile, or the saved pair may no longer be valid), and an exception raised while unwinding replaces the statement's real result and escapes the procedure's own EXCEPTION handler. Names that still match an object are restored in its stored spelling.
    • useSchema

      public void useSchema(String name)
    • useDatabaseReference

      public void useDatabaseReference(String resolvedName)
      USE DATABASE as a SQL reference resolves it — EXACTLY: the reference's resolved name (a bare one folded to upper case, a quoted one verbatim) must equal a stored name, so "audit_db" does not select AUDIT_DB and a bare mixeddb does not select "MiXedDb". A miss names nothing — live answers every failed USE with the same sentence — and leaves the context as it was.
      Parameters:
      resolvedName - the database reference, resolved
    • useSchemaReference

      public void useSchemaReference(String resolvedDatabase, String resolvedSchema)
      USE SCHEMA as a SQL reference resolves it, exactly as useDatabaseReference(java.lang.String) does, for a schema of the named database or, with no database part, of the current one. Both parts resolve before anything moves, so a missing schema leaves the current database unchanged too.
      Parameters:
      resolvedDatabase - the database part, resolved, or null for the current database
      resolvedSchema - the schema part, resolved
    • getCurrentDatabase

      public String getCurrentDatabase()
    • getCurrentSchema

      public String getCurrentSchema()
    • resolveTable

      public Table resolveTable(String qualifiedName)
    • setAccountLocator

      public void setAccountLocator(String locator)
      The account locator a name may lead with — set from the engine's configuration, upper-cased as a bare identifier folds; null leaves every name as written.
      Parameters:
      locator - the locator CURRENT_ACCOUNT() answers with
    • withoutAccount

      public String[] withoutAccount(String[] parts, int objectParts)
      An object name without the account locator it may lead with. A fully qualified name has up to objectParts parts (three for a table or view, two for a schema); live accepts one more in front when it is THIS account's locator — am68630.db.s.t, a quoted "AM68630" too — and resolves the rest exactly as the shorter spelling. Any other extra part, a wrong account or a fifth part, names nothing and is refused in the sentence live gives.
      Parameters:
      parts - the resolved parts (a bare one folded, a quoted one verbatim)
      objectParts - how many parts the name may have without the account
      Returns:
      the parts naming the object within the account
    • resolveTable

      public Table resolveTable(QualifiedName written)
    • resolveTableAsWritten

      public Table resolveTableAsWritten(String qualifiedName, String reportedKind)
      The table a QUERY or DML statement named, with a miss reported the way Snowflake reports it there: the name exactly as the writer spelled it when they spelled it bare, expanded in full when they supplied any qualifier at all, and under reportedKind — Object for a FROM clause, an UPDATE or a DELETE, Table for INSERT and DESCRIBE. Measured on a real account: SELECT 1 FROM nosuch answers Object 'NOSUCH' … while SELECT 1 FROM s.nosuch answers Object 'DB.S.NOSUCH' …. DDL differs — it always spells the name in full — which is what plain resolveTable(QualifiedName) does.
    • resolveTableAsWritten

      public Table resolveTableAsWritten(String qualifiedName, String reportedKind, String lookup)
      resolveTableAsWritten(String, String) for a lookup a query does not make. With no current database, a schema-qualified name is refused naming that lookup: CLONE for a CLONE source, DUPLICATE for a LIKE source, where every FROM clause says SELECT (live-verified).
      Parameters:
      lookup - what the refusal names when the session cannot place a schema-qualified name
    • resolveTableAsWritten

      public Table resolveTableAsWritten(QualifiedName written, String reportedKind)
    • hasTableAsWritten

      public boolean hasTableAsWritten(QualifiedName written)
      Whether the table a SQL reference names exists, asked without the throw. False for a missing table and for a name the session cannot place: a bare one with no current schema, or a schema-qualified one with no current database. A database or schema the reference does name must still exist.
      Parameters:
      written - the reference, resolved part by part
      Returns:
      whether the table exists
    • resolveView

      public View resolveView(String qualifiedName)
    • resolveView

      public View resolveView(QualifiedName written)
    • resolveCortexSearchService

      public CortexSearchService resolveCortexSearchService(String qualifiedName)
      A Cortex search service by name, however much of the path the caller wrote. The owning schema is resolved first so a missing DATABASE or SCHEMA is reported as such, and only a resolvable schema that lacks the service reports the service missing.
    • resolveCortexSearchService

      public CortexSearchService resolveCortexSearchService(QualifiedName qn)
    • hasCortexSearchService

      public boolean hasCortexSearchService(QualifiedName qn)
      Whether that service exists, without the throw — what CREATE … IF NOT EXISTS asks.
    • requireOwningSchema

      public Schema requireOwningSchema(QualifiedName written)
      The schema an object name passes through, which must exist even where the object itself need not: DROP … IF EXISTS and TRUNCATE … IF EXISTS forgive only the object's own absence (live-verified). A name the session cannot place is refused naming the statement.
      Parameters:
      written - the object's name, resolved part by part
      Returns:
      the schema that holds, or would hold, the object
    • resolveSchema

      public Schema resolveSchema(String qualifiedName)
    • resolveSchema

      public Schema resolveSchema(QualifiedName written)
    • createWarehouse

      public void createWarehouse(String name, WarehouseSize size)
    • dropWarehouse

      public void dropWarehouse(String name)
    • createComputePool

      public void createComputePool(ComputePool pool)
      A real account phrases the duplicate as a generic object clash, not a pool-specific one.
    • hasComputePool

      public boolean hasComputePool(String name)
    • getComputePool

      public ComputePool getComputePool(String name)
    • dropComputePool

      public void dropComputePool(String name)
    • getComputePools

      public List<ComputePool> getComputePools()
      Every pool, sorted by name — the order SHOW COMPUTE POOLS lists them in.
    • hasWarehouse

      public boolean hasWarehouse(String name)
      Whether that warehouse exists, without the throw — for the statements that must VALIDATE a warehouse they only reference.
    • getWarehouse

      public Warehouse getWarehouse(String name)
    • getAllWarehouses

      public List<Warehouse> getAllWarehouses()
    • useWarehouse

      public void useWarehouse(String name)
    • getCurrentWarehouse

      public String getCurrentWarehouse()
    • getCurrentWarehouseObject

      public Warehouse getCurrentWarehouseObject()
    • setS3PathResolver

      public void setS3PathResolver(S3PathResolver s3PathResolver)
      Set the resolver used to map s3:// stage URLs to local paths (see S3PathResolver).
    • setSessionContext

      public void setSessionContext(SessionContext sessionContext)
      Set the session context used to stamp object ownership at CREATE time.
    • currentRoleForOwner

      public String currentRoleForOwner()
      The role to record as owner on newly-created objects: the session's current role, else SYSADMIN.
    • getObjectOwnerRole

      public String getObjectOwnerRole(String objectType, String objectName)
      The owner role of a schema-level object, for ownership-based authorization. Returns null when the type is not one that carries an owner here, or the object cannot be resolved.
    • currentUserForStage

      public String currentUserForStage()
      The user whose stage @~ resolves to: the session's current user, else PUBLIC.
    • useRole

      public void useRole(String roleName)
      USE ROLE <name>: switch the session's primary role; errors if the role does not exist.

      The refusal NAMES NOTHING — live answers "Object does not exist, or operation cannot be performed." for a role that is not there, without quoting the name the way its object-not-found sentences do elsewhere. That is deliberate on a real account: a role a session cannot use is indistinguishable from one that does not exist, so the message cannot confirm either.

    • useSecondaryRoles

      public void useSecondaryRoles(String spec)
      USE SECONDARY ROLES {ALL | NONE | <role>}: adjust which non-primary roles' privileges are active.
    • recordDropped

      public void recordDropped(String key, DroppedObject dropped)
      Record a dropped object's snapshot under "KIND:fqName" so a subsequent UNDROP can restore it.
    • takeDropped

      public DroppedObject takeDropped(String key)
      Remove and return the most recent dropped-object snapshot for "KIND:fqName", or null if none.
    • restoreDatabase

      public void restoreDatabase(Database database)
      Re-insert a previously-dropped database object (UNDROP DATABASE).
    • getObjectTagValue

      public String getObjectTagValue(String tagName, String objectName, String domain)
      Read the value of a tag set on an object (SYSTEM$GET_TAG); null if the object or tag is absent.
    • createStage

      public void createStage(String name, StageType type, String url)
    • createStage

      public void createStage(String name, StageType type, String url, String fileFormat, boolean encryption, String comment)
    • dropStage

      public void dropStage(String name)
    • renameStage

      public void renameStage(String name, String newName)
      ALTER STAGE … RENAME TO — rekey the schema's map and rename the object itself.
    • getStage

      public Stage getStage(String name)
    • resolveStream

      public Stream resolveStream(String qualifiedName)
      Resolve a stream by its (optionally schema- or db-qualified) name against the current context — SYSTEM$STREAM_HAS_DATA('SCHEMA.STREAM') passes the qualified text at runtime. Returns null when the schema or stream does not exist.
    • addFileFormat

      public void addFileFormat(String qualifiedName, FileFormat fileFormat)
    • getFileFormat

      public FileFormat getFileFormat(String name)
    • hasFileFormat

      public boolean hasFileFormat(String name)
    • dropFileFormat

      public void dropFileFormat(String name)
    • getPipe

      public Pipe getPipe(String name)
    • getAllStages

      public List<Stage> getAllStages()
    • createTag

      public void createTag(String name)
    • createTag

      public void createTag(String name, List<String> allowedValues, String comment)
    • dropTag

      public void dropTag(String name)
    • getTag

      public Tag getTag(String name)
    • hasTag

      public boolean hasTag(String name)
    • getAllTags

      public List<Tag> getAllTags()
    • renameTag

      public void renameTag(String oldName, String newName)
    • renameMaskingPolicy

      public void renameMaskingPolicy(String oldName, String newName)
    • renameJoinPolicy

      public void renameJoinPolicy(String oldName, String newName)
    • renameAggregationPolicy

      public void renameAggregationPolicy(String oldName, String newName)
    • renameProjectionPolicy

      public void renameProjectionPolicy(String oldName, String newName)
    • renameRowAccessPolicy

      public void renameRowAccessPolicy(String oldName, String newName)
    • findRowAccessPolicy

      public RowAccessPolicy findRowAccessPolicy(String qualifiedName)
      The row access policy a possibly-qualified name resolves to, or null when nothing does — the lookup the attachment statements need before they may touch the object they attach to.
      Parameters:
      qualifiedName - the policy name as written: bare, schema-qualified or fully qualified
      Returns:
      the policy, or null when the name resolves to no policy in that schema
    • findJoinPolicy

      public JoinPolicy findJoinPolicy(String qualifiedName)
      The join policy a possibly-qualified name resolves to, or null when nothing does.
      Parameters:
      qualifiedName - the policy name as written
      Returns:
      the policy, or null when the name resolves to none in that schema
    • isJoinPolicyInUse

      public boolean isJoinPolicyInUse(String policyName)
      True when a join policy is attached to any table — live refuses to drop or replace one.
    • findAggregationPolicy

      public AggregationPolicy findAggregationPolicy(String qualifiedName)
      The aggregation policy a possibly-qualified name resolves to, or null when nothing does.
      Parameters:
      qualifiedName - the policy name as written
      Returns:
      the policy, or null when the name resolves to none in that schema
    • isAggregationPolicyInUse

      public boolean isAggregationPolicyInUse(String policyName)
      True when an aggregation policy is attached to any table — live refuses to drop or replace one.
    • findProjectionPolicy

      public ProjectionPolicy findProjectionPolicy(String qualifiedName)
      The projection policy a possibly-qualified name resolves to, or null when nothing does.
      Parameters:
      qualifiedName - the policy name as written
      Returns:
      the policy, or null when the name resolves to none in that schema
    • isProjectionPolicyInUse

      public boolean isProjectionPolicyInUse(String policyName)
      True when a projection policy is attached to any column — live refuses to drop or replace one.
    • findContact

      public Contact findContact(String qualifiedName)
      The contact a possibly-qualified name resolves to, or null when nothing does.
      Parameters:
      qualifiedName - the contact name as written: bare, schema-qualified or fully qualified
      Returns:
      the contact, or null when the name resolves to none in that schema
    • findMaskingPolicy

      public MaskingPolicy findMaskingPolicy(String qualifiedName)
      The masking policy a possibly-qualified name resolves to, or null when nothing does. A name whose SCHEMA is missing does not answer null — it raises the schema's own refusal, which is what live answers there too.
      Parameters:
      qualifiedName - the policy name as written: bare, schema-qualified or fully qualified
      Returns:
      the policy, or null when the name resolves to no policy in that schema
    • qualifiedObjectName

      public String qualifiedObjectName(String qualifiedName)
      A schema-level object's name spelled in full — database.schema.OBJECT — resolving however much of the path was written against the session, the way a reference to it resolves. Live reports an attached policy this way whatever the attaching statement wrote, so a name recorded for later display is qualified once, when it is attached, rather than at every read.
      Parameters:
      qualifiedName - the name as written: bare, schema-qualified or already fully qualified
      Returns:
      the fully qualified name, upper-cased in its last part as the reference resolved it
    • createUser

      public void createUser(String name)
    • createUser

      public void createUser(String name, String password, String defaultRole)
    • dropUser

      public void dropUser(String name)
    • hasUser

      public boolean hasUser(String name)
      Whether a user of this name exists, for callers that must not throw on a miss.
    • getUser

      public User getUser(String name)
    • getAllUsers

      public List<User> getAllUsers()
    • createRole

      public void createRole(String name)
    • dropRole

      public void dropRole(String name)
    • isSystemRole

      public boolean isSystemRole(String roleName)
      Check if a role is a system role
    • getRole

      public Role getRole(String name)
    • getAllRoles

      public List<Role> getAllRoles()
    • grantRoleToUser

      public void grantRoleToUser(String roleName, String userName)
    • revokeRoleFromUser

      public void revokeRoleFromUser(String roleName, String userName)
    • grantPrivilegeToRole

      public void grantPrivilegeToRole(String privilege, String objectType, String objectName, String roleName)
    • revokePrivilegeFromRole

      public void revokePrivilegeFromRole(String privilege, String objectType, String objectName, String roleName)
    • grantPrivilegeToUser

      public void grantPrivilegeToUser(String privilege, String objectType, String objectName, String userName)
    • revokePrivilegeFromUser

      public void revokePrivilegeFromUser(String privilege, String objectType, String objectName, String userName)
    • grantColumnPrivilegeToRole

      public void grantColumnPrivilegeToRole(String privilege, String objectType, String objectName, String columnName, String roleName)
    • revokeColumnPrivilegeFromRole

      public void revokeColumnPrivilegeFromRole(String privilege, String objectType, String objectName, String columnName, String roleName)
    • grantColumnPrivilegeToUser

      public void grantColumnPrivilegeToUser(String privilege, String objectType, String objectName, String columnName, String userName)
    • revokeColumnPrivilegeFromUser

      public void revokeColumnPrivilegeFromUser(String privilege, String objectType, String objectName, String columnName, String userName)
    • grantRoleToRole

      public void grantRoleToRole(String grantedRoleName, String targetRoleName)
    • revokeRoleFromRole

      public void revokeRoleFromRole(String revokedRoleName, String targetRoleName)
    • renameDatabase

      public void renameDatabase(String oldName, String newName)
    • renameTable

      public void renameTable(String qualifiedName, String newName)
    • swapTables

      public void swapTables(String nameA, String nameB)
      ALTER TABLE a SWAP WITH b — the two tables exchange names in place, so each keeps its own columns, constraints and comment but answers to the other's name (and schema). Both must exist; resolution failures throw before anything mutates.
    • moveTable

      public void moveTable(String sourceQualifiedName, String targetDatabase, String targetSchema, String newName)
      Move a table to a (possibly different) schema/database, optionally renaming it — the qualified-target form of ALTER TABLE ... RENAME TO db.schema.name. The destination database and schema must already exist (else getDatabase(java.lang.String)/getSchema throw), and no table of the new name may already exist there. Membership is checked before any mutation, so a rejected move leaves the catalog untouched.
    • moveView

      public void moveView(String sourceQualifiedName, String targetDatabase, String targetSchema, String newName)
      Move a view to a (possibly different) schema/database under a new name — ALTER VIEW's RENAME TO, whose new name the session's context places. The destination must exist and hold no view of that name, both checked before anything changes; a move within the view's own schema is a rename.
    • renameView

      public void renameView(String qualifiedName, String newName)
    • renameUser

      public void renameUser(String oldName, String newName)
    • renameRole

      public void renameRole(String oldName, String newName)
    • renameWarehouse

      public void renameWarehouse(String oldName, String newName)