Class QueryExecutor
-
Constructor Summary
ConstructorsConstructorDescriptionQueryExecutor(Catalog catalog, StorageEngine storageEngine, FunctionRegistry functionRegistry, TransactionManager transactionManager, EngineConfig config) -
Method Summary
Modifier and TypeMethodDescriptionvoidbackfillColumn(String tableName, TableColumn newColumn) Backfill every existing row of a table after ALTER TABLE ADD COLUMN, appending one value for the new column so stored rows match the widened schema — otherwise every read of the new column throws IndexOutOfBounds.baseTableRowCount(Table owner) The rows a catalog table holds, as this transaction sees them, or null when the table's rows are not reachable — the bound the account gives a COUNT over it.voidcoerceRowTypesLenient(Table table, Row row) Lenient per-column coercion for CTAS rows: coerce each value to the created table's column type when the conversion works, and keep the ORIGINAL value when it does not.columnValueRange(Table owner, String columnName) A catalog column's statistics: the interval between the least and the greatest value in the WHOLE table — every row, whatever the query's WHERE keeps — which is what the account tags the column by, and whether any row holds a NULL, which decides whether the column may answer one.voidAdvance the offset of streams read by the last CTAS source SELECT.copyPatternPrefix(String fromLocation) The prefix PATTERN-matching prepends to a staged file's root-relative name, mirroring the shape of the account's internal paths:stages/<name>/for a named stage,tables/<name>/for a table stage andusers/<user>/for the user stage (the account puts an opaque id where the name sits here).booleanWhether the SELECT clause executing on this thread reads past its table's statistics — a join, a grouping key, a HAVING, or a WHERE the statistics cannot prove — so that its COUNT is tagged by its declared width and a typeof over COUNT, MIN or MAX is no longer answered from them.The instant the most recent outermost statement pinned, for the log to record alongside its SQL.DESCRIBE RESULT '<queryId>' | LAST_QUERY_ID() — the column metadata of a prior query's cached result.voidemptyTableContents(String fullyQualifiedName) Discard every row offullyQualifiedName, shared by TRUNCATE TABLE and INSERT OVERWRITE.voidenforceColumnConstraints(Table table, Row row) Enforce column constraints at statement time on the COPY write path: coerce values to the column type (only when constraints.enforce.types is on), then check NOT NULL (always — Snowflake enforces NOT NULL, unlike the informational PK/UK/FK).voidenforceColumnConstraintsForDml(Table table, Row row) The DML flavour ofenforceColumnConstraints(Table, Row): INSERT,INSERT … SELECT, UPDATE and MERGE all report a write violation inside a per-statement envelope naming the table and the column — live-verified verbatim,DML operation to table NN failed on column C with error: NULL result in a non-nullable column— around the same inner sentences the COPY path reports bare.voidenforceColumnConstraintsForDml(Table table, Row row, boolean boundToColumnSlot) enforceColumnConstraintsForDml(Table, Row, boolean, String)naming the table bare.voidenforceColumnConstraintsForDml(Table table, Row row, boolean boundToColumnSlot, String writtenName) The write-time constraints of one row, each failure wrapped in the DML envelope that names the table AS THE STATEMENT WROTE IT —TEST_DB.TEST_SCHEMA.TWOfor a qualified INSERT,TWOfor a bare one, four parts when the account was written (live-verified for INSERT, UPDATE, UPDATE … FROM and both MERGE branches).evaluateSystemFunction(String funcName, List<Object> args) Evaluate a SYSTEM$FUNCNAME call from expression context (no ANTLR ctx available).Execute SQL using ANTLR parsing and visitor patternexecuteCopyRefresh(String copyStatement, String prefix, String modifiedAfter) ALTER PIPE … REFRESH: run the pipe's stored COPY, but restrict the files it loads to those whose stage-relative path starts withprefixand/or whose last-modified time is strictly aftermodifiedAfter(matching Snowflake's REFRESH PREFIX / MODIFIED_AFTER).Execute the source SELECT of a CTAS in a stream-consuming context.Execute DELETE from parsed contextExecute INSERT from parsed contextLIST @stage [PATTERN] — live's four columns over the stage's whole tree.Execute MERGE from parsed contextSnowflake multi-table INSERT — route each row of the subquery to one or more target tables.PUT — live's nine-column result shape: compressions, the constant ENCRYPTED marker, and a message cell.REMOVE/RM @stage [PATTERN = '…'] — delete staged files (optionally matching a regex pattern).executeScriptingFunctionBody(Function function, List<Object> args) Execute SELECT from parsed contextvoidexecuteTruncate(String tableName, boolean ifExists) Execute TRUNCATE TABLEExecute UPDATE from parsed contextexecuteWithLateralContext(String sql, Map<String, Object> lateralContext) getFullyQualifiedTableName(String tableName) The session's procedural (Snowflake Scripting) executor — used to resolve :name bind variables.Resolver for s3:// (and S3-backed @stage) references to local files; null if no config was supplied.static byte[]gzipBytes(byte[] bytes) The gzip ofbytes; GZIPOutputStream writes no timestamp, so equal input gives equal output.booleanisDurableStatement(String sql) booleanWhether a correlated / lateral re-execution is on the stack.booleanisProceduralBlock(String sql) True whensqlparses as a single Snowflake-Scripting block —BEGIN … ENDorDECLARE … BEGIN … END.booleanisQueryStatement(String sql) True whensqlparses as a single query statement (SELECT / WITH … SELECT).booleanWhethersqlis exactly ONE plain (non-procedural) SQL statement — a bareSELECT …/UPDATE …and nothing else.listCopyFiles(Path baseDir, String pattern, List<String> files) Regular files inbaseDir, narrowed either by an explicitFILES = (…)list or by aPATTERNregex — never by both.The staged files a COPY-family statement addresses.The syntax errorsqlearns when the FIRST thing wrong with it is a statement inside a block that lacks its semicolon, or null for any other text.voidmoveTableStorage(String oldName, String targetDatabase, String targetSchema, String newShortName) Re-key a moved table's row storage to a new database/schema/name (cross-schema RENAME TO).booleanparsesAsScript(String sql) Whethersqlparses at all under the engine's grammar.proceduralBlockOf(String sql) queryStatementOf(String sql) The parsed scriptsqlforms when it is a single query statement, or null when it is not one.voidrejectAggregatesInWhere(FrostlakeParser.WhereClauseContext where, Table table) An UPDATE's or DELETE's WHERE refuses an aggregate as a query's does:Invalid aggregate function in where clause [COUNT(*)](live-verified).voidrenameTableStorage(String oldName, String newShortName) Re-key a renamed table's row storage: the new name keeps the old table's database/schema.voidThrow the syntax error of a body that OPENS a scripting block — its first token isBEGINorDECLARE— but does not parse as one; a body that opens no block, or parses as something else, returns quietly.voidThrow the syntax error of a block-opening body that RUNS OUT before its block closes — the parse error sits at end of input, so the engine has read every token and positively knows the block never ended, which a real account also refuses at CREATE.voidrequireRelations(org.antlr.v4.runtime.tree.ParseTree statement) voidrequireSecurable(String objectType, String[] parts) The object a GRANT, a REVOKE or a SHOW GRANTS names must exist, and is found before anything else the statement names (live-verified).voidrequireSecurable(String objectType, String[] parts, Integer signatureArity) requireSecurable(String, String[])with a routine's written argument count: a function none of whose overloads takes that many arguments names nothing (live-verified).voidFind every relation an INSERT's source query reads, in the order written, and refuse the first that names nothing, before the target is looked up.voidresetCopyLoadHistory(String fullyQualifiedTableName) Forget a table's COPY load history — TRUNCATE and CREATE OR REPLACE / DROP TABLE all do.voidresetInternalStageDir(String stageName) A NEW internal named stage starts EMPTY, exactly like a real account's: the engine-managed directory is durable on disk, so without this a re-created stage would inherit the files a dropped same-name predecessor staged.voidresetInternalTableStageDir(String tableName) The same reset for a TABLE's implicit stage — a new table's stage is empty likewise.resolveColumnInTables(Row row, List<Table> tables, Map<String, Table> aliasToTable, String qualifiedName) Resolve a (possibly qualified) column reference against a multi-table row context — the alias-aware resolution used by JOIN evaluation, exposed for the AST evaluator so a parsed Expression can be evaluated directly over joined rows (e.g.resolveColumnInTables(Row row, List<Table> tables, Map<String, Table> aliasToTable, String qualifiedName, int[] resolvedOffset) Resolve likeresolveColumnInTables(Row, List, Map, String), additionally reporting HOW the reference resolved throughresolvedOffset[0]: the flat row offset when the value came from the plain table-column scan (a fixed layout position the caller may cache for this context), left untouched when it resolved any other way (literal fallback, merged join key — per-row decisions that must re-run).resolveCopyBaseDir(String fromLocation) Resolve anobjectNameparse node to the name it denotes:IDENTIFIER(<expr>)evaluates the expression (a string literal or a session/bind variable) to the name; otherwise it is the literal qualified name as written.String[]Canonical name PARTS of anobjectName— one element per dotted level, so a quoted identifier containing a dot stays one part where splittingresolveObjectName(dev.frostlake.parser.FrostlakeParser.ObjectNameContext)'s joined spelling would break it.resolveRelationColumns(String definition, List<String> explicitColumnNames) resolveRelationShape(String definition, List<String> explicitColumnNames) A relation's column list from its definition's SHAPE alone — no row is read and no value computed (seeRelationShapeOnly), which is how CREATE VIEW learns its columns: a value-time fault in the body is the reader's, not the creator's.resolveStagedFile(Path baseDir, String name) Resolve a stage reference (e.g.resolveStageFilePath(String location) Resolve a location string (e.g.Resolve a view's body shape at CREATE where the view will live, asexecuteInViewScope(java.lang.String, java.lang.String)reads it: a bare name in the body is the view's schema's, and a missing one is named there.Back-compat single-table resolver: the first (often only) branch's base table.Resolve the base tables of a view eligible for change tracking (CREATE STREAM ON VIEW).voidsetDatabaseEngine(DatabaseEngine engine) voidsetNextStatementInstant(Instant instant) The instant the NEXT statement should call "now", set only by write-ahead-log replay so a re-executed statement resolves CURRENT_TIMESTAMP to the value it was originally written with.voidsetSecurityManager(SecurityManager securityManager) voidsetStreamManager(StreamManager streamManager) voidsetTaskScheduler(TaskScheduler taskScheduler) showQueryHistory(Integer limit) stagedDisplayName(String fromLocation, Path file) How LIST and REMOVE display a staged file, live-verified: the path relative to the STAGE ROOT (not the referenced subdirectory), prefixed with the lowercase stage name for a named stage; user and table stages show the bare root-relative path.Encode a stage reference as a COPY location string:@name[/path],@~[/path], or@%table[/path].intstatementCountOf(String sql) How many statementssqlparses into — every stage of every flow chain — or 0 when it does not parse.longstoredRowCount(String storageKey) The rows a catalog table's storage holds right now, by its storage key, or -1 when there is none: a metadata question, as live's planner asks it before any row is read.longstoredRowCountOf(String writtenName) storedRowCount(java.lang.String)for a table named as a query writes it, or -1 when the name reaches no storage.subqueryStatement(String sql) The querysqlparses to, read from the cache statements use, or null when it is not one query.voidswapTables(String tableA, String tableB) ALTER TABLE a SWAP WITH b — exchange the two tables' row storage (compatible structure assumed).voidwriteCtasRow(Table table, Row row, String envelopeName) A CTAS row written into the declared types of its column list, as live writes it: each value is converted to its column the way an INSERT converts it — a number rounded to the scale, text parsed — and a value that does not fit is refused inside the DML envelope naming the table and the column ("DML operation to table DB.S.T failed on column X with error: String 'abcd' is too long and would be truncated").
-
Constructor Details
-
QueryExecutor
public QueryExecutor(Catalog catalog, StorageEngine storageEngine, FunctionRegistry functionRegistry, TransactionManager transactionManager, EngineConfig config)
-
-
Method Details
-
setStreamManager
-
setTaskScheduler
-
setDatabaseEngine
-
getDatabaseEngine
-
setSecurityManager
-
getSecurityManager
-
getSessionVariables
-
getResultCache
-
evaluateSystemFunction
Evaluate a SYSTEM$FUNCNAME call from expression context (no ANTLR ctx available). -
getQueryHistoryTracker
-
execute
Execute SQL using ANTLR parsing and visitor pattern -
setNextStatementInstant
The instant the NEXT statement should call "now", set only by write-ahead-log replay so a re-executed statement resolves CURRENT_TIMESTAMP to the value it was originally written with. Consumed by the nextexecute(java.lang.String); null means read the wall clock, which is every normal call. -
currentStatementInstant
The instant the most recent outermost statement pinned, for the log to record alongside its SQL. Read after execution — at commit — so it is the remembered value, not a fresh clock reading. -
isDurableStatement
-
isQueryStatement
True whensqlparses as a single query statement (SELECT / WITH … SELECT). Lets a SQL-UDF body that is a query be distinguished from a bare scalar expression via the parse tree, not a string prefix (soWITH … SELECTCTE bodies are recognised too). A body that does not parse as a statement (e.g.x * 2) returns false. Cached per body. -
subqueryStatement
The querysqlparses to, read from the cache statements use, or null when it is not one query. A subquery's text is a statement of its own, so its shape can be read without running it. -
storedRowCount
The rows a catalog table's storage holds right now, by its storage key, or -1 when there is none: a metadata question, as live's planner asks it before any row is read. -
storedRowCountOf
storedRowCount(java.lang.String)for a table named as a query writes it, or -1 when the name reaches no storage. -
isProceduralBlock
True whensqlparses as a single Snowflake-Scripting block —BEGIN … ENDorDECLARE … BEGIN … END. Sibling ofisQueryStatement(String): the decision is made on the parse tree, never on a string prefix, so the transaction statementBEGIN;(a different grammar rule that also starts with BEGIN) is correctly not a block, while a lower-cased or multi-line block is.Used to compile a
LANGUAGE SQLstored-procedure body at CREATE time: Snowflake requires such a body to be a scripting block and rejects a bare statement outright. -
reportBlockSyntaxError
Throw the syntax error of a body that OPENS a scripting block — its first token isBEGINorDECLARE— but does not parse as one; a body that opens no block, or parses as something else, returns quietly.The CREATE-time body checks fail OPEN on a body this grammar cannot read (see the note on
parsesAsScript(String)), which is right there — the body may use a construct the engine does not model. At CALL time the body has to RUN, so its real parse error is the honest answer; without this the caller falls through to the expression evaluator and reports whatever opaque failure that produces. -
reportUnterminatedBlock
Throw the syntax error of a block-opening body that RUNS OUT before its block closes — the parse error sits at end of input, so the engine has read every token and positively knows the block never ended, which a real account also refuses at CREATE. Any other parse failure returns quietly: this grammar is a SUBSET of Snowflake's, so a mid-body error may be a construct the engine does not model, and the CREATE-time body checks fail OPEN on those (see the note onparsesAsScript(String)). -
queryStatementOf
The parsed scriptsqlforms when it is a single query statement, or null when it is not one. The parse-tree half ofisQueryStatement(String), for the CREATE-time SQL-UDF body check; unlike that method this parses afresh rather than consulting the hot-path cache, because it is only ever reached once per CREATE. -
statementCountOf
How many statementssqlparses into — every stage of every flow chain — or 0 when it does not parse. The CREATE-time SQL-UDF body check refuses a body of more than one. -
missingTerminatorRefusal
The syntax errorsqlearns when the FIRST thing wrong with it is a statement inside a block that lacks its semicolon, or null for any other text. The engine read that statement whole, so the fault is positively known rather than a construct the grammar lacks, and a CREATE PROCEDURE refuses it as the account does. -
proceduralBlockOf
-
parsesAsScript
Whethersqlparses at all under the engine's grammar. Frostlake's grammar is a SUBSET of Snowflake's, so a parse FAILURE means "this engine does not recognise some construct" — never "Snowflake would reject it". The CREATE-time routine-body checks use this to fail OPEN: they only reject a body whose shape they can positively read and know to be wrong. -
isSinglePlainStatement
Whethersqlis exactly ONE plain (non-procedural) SQL statement — a bareSELECT …/UPDATE …and nothing else. This is the one routine-body shape the engine can positively call wrong: Snowflake requires a LANGUAGE SQL procedure body to be a scripting block and rejects a bare statement outright. A body that does not parse, or parses as several statements, or contains any procedural construct, is NOT this shape. -
isInLateralExecution
public boolean isInLateralExecution()Whether a correlated / lateral re-execution is on the stack. -
executeWithLateralContext
-
executeInsertFromContext
Execute INSERT from parsed context -
executeMultiTableInsert
Snowflake multi-table INSERT — route each row of the subquery to one or more target tables. INSERT [OVERWRITE] ALL INTO ... (unconditional), or INSERT [OVERWRITE] {FIRST | ALL} WHEN cond THEN INTO ... [ELSE INTO ...]. FIRST stops at the first matching WHEN; ALL applies every matching WHEN; ELSE applies only when no WHEN matched. -
executeSelectFromContext
Execute SELECT from parsed context -
executeUpdateFromContext
Execute UPDATE from parsed context -
executeDeleteFromContext
Execute DELETE from parsed context -
enforceColumnConstraints
Enforce column constraints at statement time on the COPY write path: coerce values to the column type (only when constraints.enforce.types is on), then check NOT NULL (always — Snowflake enforces NOT NULL, unlike the informational PK/UK/FK). The violation sentences here are BARE — a COPY reports them as the file'sfirst_error, naming the column separately infirst_error_column_name. DML statements go throughenforceColumnConstraintsForDml(Table, Row), which wraps the same sentences in the per-statement envelope live uses. -
enforceColumnConstraintsForDml
The DML flavour ofenforceColumnConstraints(Table, Row): INSERT,INSERT … SELECT, UPDATE and MERGE all report a write violation inside a per-statement envelope naming the table and the column — live-verified verbatim,DML operation to table NN failed on column C with error: NULL result in a non-nullable column— around the same inner sentences the COPY path reports bare. Enforcement is per column in declaration order, so the first violating column names the failure. -
enforceColumnConstraintsForDml
enforceColumnConstraintsForDml(Table, Row, boolean, String)naming the table bare. -
enforceColumnConstraintsForDml
public void enforceColumnConstraintsForDml(Table table, Row row, boolean boundToColumnSlot, String writtenName) The write-time constraints of one row, each failure wrapped in the DML envelope that names the table AS THE STATEMENT WROTE IT —TEST_DB.TEST_SCHEMA.TWOfor a qualified INSERT,TWOfor a bare one, four parts when the account was written (live-verified for INSERT, UPDATE, UPDATE … FROM and both MERGE branches). The spelling travels as a PARAMETER from the handler that read the statement: a thread-local for it leaked into the next statement once.- Parameters:
writtenName- the table as written, upper-cased per part, or null for the bare catalog name
-
writeCtasRow
A CTAS row written into the declared types of its column list, as live writes it: each value is converted to its column the way an INSERT converts it — a number rounded to the scale, text parsed — and a value that does not fit is refused inside the DML envelope naming the table and the column ("DML operation to table DB.S.T failed on column X with error: String 'abcd' is too long and would be truncated"). A NULL in a NOT NULL column is the bare "NULL result in a non-nullable column" there (live-verified).- Parameters:
envelopeName- the table as the CTAS envelope names it, one level up from how it was written
-
coerceRowTypesLenient
Lenient per-column coercion for CTAS rows: coerce each value to the created table's column type when the conversion works, and keep the ORIGINAL value when it does not. The result-column types a SELECT reports are best-effort (an expression column can say NUMBER while a row carries a UUID string), so the strict INSERT-style coercion would reject rows Snowflake accepts. -
executeTruncate
Execute TRUNCATE TABLE -
emptyTableContents
Discard every row offullyQualifiedName, shared by TRUNCATE TABLE and INSERT OVERWRITE.Under deferred-apply this MUST route through the write set (like INSERT/UPDATE): every committed row becomes a pending delete and the transaction's own buffered inserts/updates for the table are dropped, so the rest of the transaction sees the table empty and the change applies atomically at COMMIT (a ROLLBACK restores the rows). Clearing the base store directly would leave this transaction's not-yet-committed inserts in place, to reappear on the next read — which is precisely what made INSERT OVERWRITE APPEND to, instead of replace, rows written earlier in the same transaction (the stage/rebuild pattern
INSERT INTO tmp …; INSERT OVERWRITE INTO tmp … SELECT … FROM tmp …). A transaction is begun when none is active, as INSERT does, so an autocommit truncate applies at statement end and an explicit one stays rollback-safe. -
executeMergeFromContext
Execute MERGE from parsed context -
executeCopyIntoFromContext
-
executePutFromContext
PUT — live's nine-column result shape: compressions, the constant ENCRYPTED marker, and a message cell. AUTO_COMPRESS defaults to TRUE, gzipping an uncompressed source and renaming the targetname.gz; re-PUTting an identical file answers SKIPPED with live's own sentence (OVERWRITE=TRUE forces the upload). -
gzipBytes
The gzip ofbytes; GZIPOutputStream writes no timestamp, so equal input gives equal output.- Throws:
IOException
-
executeGetFromContext
-
executeRemoveFromContext
REMOVE/RM @stage [PATTERN = '…'] — delete staged files (optionally matching a regex pattern). -
stagedDisplayName
How LIST and REMOVE display a staged file, live-verified: the path relative to the STAGE ROOT (not the referenced subdirectory), prefixed with the lowercase stage name for a named stage; user and table stages show the bare root-relative path. -
executeListFromContext
LIST @stage [PATTERN] — live's four columns over the stage's whole tree. -
executeCopyRefresh
ALTER PIPE … REFRESH: run the pipe's stored COPY, but restrict the files it loads to those whose stage-relative path starts withprefixand/or whose last-modified time is strictly aftermodifiedAfter(matching Snowflake's REFRESH PREFIX / MODIFIED_AFTER). Either filter may be null (absent). The filters are scoped to this single COPY and cleared afterwards. -
resolveStageFilePath
Resolve a stage reference (e.g.@stg/script.sql) to its local file path — forEXECUTE IMMEDIATE FROM. -
resolveStageFilePath
Resolve a location string (e.g.'file://…/script.sql') to its local file path. -
resolveCopyBaseDir
-
stageRefToLocation
Encode a stage reference as a COPY location string:@name[/path],@~[/path], or@%table[/path]. -
resetInternalStageDir
A NEW internal named stage starts EMPTY, exactly like a real account's: the engine-managed directory is durable on disk, so without this a re-created stage would inherit the files a dropped same-name predecessor staged. -
resetInternalTableStageDir
The same reset for a TABLE's implicit stage — a new table's stage is empty likewise. -
listCopyFiles
Regular files inbaseDir, narrowed either by an explicitFILES = (…)list or by aPATTERNregex — never by both. Live-verified on a real account: when a statement carries both, the PATTERN is ignored outright.FILES = ('good1.csv','good2.csv')besidePATTERN = '.*good1.*'loaded BOTH files, andFILES = ('good1.csv')beside a pattern matching nothing still loaded good1 — so a FILES list is the whole selection, not a candidate set the pattern then filters.A FILES entry is a PATH relative to the FROM location, not a bare file name: the account loads
FILES = ('sub/nested.csv')from@stageand reports it asstage/sub/nested.csv. Entries are returned in the order the statement wrote them (duplicates collapsed); a directory scan keeps its name order. -
listCopyFiles
public List<Path> listCopyFiles(Path baseDir, String pattern, List<String> files, String patternPrefix) The staged files a COPY-family statement addresses.patternis a full-match regex; the string it must match ispatternPrefix + <root-relative name>— COPY passes the internal-path prefix (stages/<name>/…) because the account applies PATTERN to the file's whole internal path, not its bare name: a stage holdinggood.csvmatches'.*good\.csv'but neither'good\.csv'nor'<stage>/good\.csv'. -
copyPatternPrefix
The prefix PATTERN-matching prepends to a staged file's root-relative name, mirroring the shape of the account's internal paths:stages/<name>/for a named stage,tables/<name>/for a table stage andusers/<user>/for the user stage (the account puts an opaque id where the name sits here). Lower-cased, subpath included. -
resetCopyLoadHistory
Forget a table's COPY load history — TRUNCATE and CREATE OR REPLACE / DROP TABLE all do. -
resolveStagedFile
-
swapTables
ALTER TABLE a SWAP WITH b — exchange the two tables' row storage (compatible structure assumed). -
resolveObjectName
Resolve anobjectNameparse node to the name it denotes:IDENTIFIER(<expr>)evaluates the expression (a string literal or a session/bind variable) to the name; otherwise it is the literal qualified name as written. Lets object names be supplied dynamically (Snowflake IDENTIFIER()). -
resolveObjectNameParts
Canonical name PARTS of anobjectName— one element per dotted level, so a quoted identifier containing a dot stays one part where splittingresolveObjectName(dev.frostlake.parser.FrostlakeParser.ObjectNameContext)'s joined spelling would break it. The literal path reads the parse tree; theIDENTIFIER(<expr>)path evaluates the expression and canonicalises its VALUE per dotted part (the string IS the identifier reference, so its dots and quotes are the value's own syntax). -
renameTableStorage
Re-key a renamed table's row storage: the new name keeps the old table's database/schema. -
moveTableStorage
public void moveTableStorage(String oldName, String targetDatabase, String targetSchema, String newShortName) Re-key a moved table's row storage to a new database/schema/name (cross-schema RENAME TO). -
backfillColumn
Backfill every existing row of a table after ALTER TABLE ADD COLUMN, appending one value for the new column so stored rows match the widened schema — otherwise every read of the new column throws IndexOutOfBounds. Snowflake populates existing rows with the column's DEFAULT literal when present, otherwise NULL; the default is evaluated once (via the same path INSERT uses) and shared across rows. -
getFullyQualifiedTableName
-
resolveViewShapeInScope
public List<TableColumn> resolveViewShapeInScope(String database, String schema, String body, List<String> columnNames) Resolve a view's body shape at CREATE where the view will live, asexecuteInViewScope(java.lang.String, java.lang.String)reads it: a bare name in the body is the view's schema's, and a missing one is named there.- Parameters:
database- the view's databaseschema- the view's schemabody- the bodycolumnNames- the view's written column names, or null- Returns:
- the body's columns
-
requireSourceRelations
Find every relation an INSERT's source query reads, in the order written, and refuse the first that names nothing, before the target is looked up. Live reports a missing source relation ahead of a missing target or a bad column list, while a missing target still comes ahead of the source's column and function errors (live-verified). Nothing is read: each name is only found, the way a FROM clause finds it.- Parameters:
source- the INSERT's source query
-
requireSecurable
The object a GRANT, a REVOKE or a SHOW GRANTS names must exist, and is found before anything else the statement names (live-verified). A table and a view resolve each other, the named kind wording the miss; a schema, a database, a function, a sequence and a stage are each found in their own place, a missing container refused as such. Other kinds are not looked up.- Parameters:
objectType- the kind the statement names, upper-caseparts- the object's name, part by part
-
requireSecurable
requireSecurable(String, String[])with a routine's written argument count: a function none of whose overloads takes that many arguments names nothing (live-verified).- Parameters:
objectType- the kind the statement names, upper-caseparts- the object's name, part by partsignatureArity- the number of argument types written after the name, or null for none
-
requireRelations
public void requireRelations(org.antlr.v4.runtime.tree.ParseTree statement) -
rejectAggregatesInWhere
An UPDATE's or DELETE's WHERE refuses an aggregate as a query's does:Invalid aggregate function in where clause [COUNT(*)](live-verified).- Parameters:
where- the statement's WHERE, or nulltable- the statement's target
-
getCatalog
-
getProceduralExecutor
The session's procedural (Snowflake Scripting) executor — used to resolve :name bind variables. -
executeScriptingFunctionBody
- See Also:
-
getEngineConfig
-
getS3PathResolver
Resolver for s3:// (and S3-backed @stage) references to local files; null if no config was supplied. -
getStorageEngine
-
getFunctionRegistry
-
getTransactionManager
-
getStreamManager
-
getTaskScheduler
-
getShowExecutor
-
describeResult
DESCRIBE RESULT '<queryId>' | LAST_QUERY_ID() — the column metadata of a prior query's cached result. -
showQueryHistory
-
columnValueRange
A catalog column's statistics: the interval between the least and the greatest value in the WHOLE table — every row, whatever the query's WHERE keeps — which is what the account tags the column by, and whether any row holds a NULL, which decides whether the column may answer one. Empty for a column holding only NULLs or no rows; null for a table this executor cannot read.- Parameters:
owner- the catalog table, as the FROM clause resolved itcolumnName- the column- Returns:
- the interval, or null when the table's rows are not reachable
-
baseTableRowCount
The rows a catalog table holds, as this transaction sees them, or null when the table's rows are not reachable — the bound the account gives a COUNT over it. -
countIsUnbounded
public boolean countIsUnbounded()Whether the SELECT clause executing on this thread reads past its table's statistics — a join, a grouping key, a HAVING, or a WHERE the statistics cannot prove — so that its COUNT is tagged by its declared width and a typeof over COUNT, MIN or MAX is no longer answered from them. -
resolveViewStreamBaseTables
Resolve the base tables of a view eligible for change tracking (CREATE STREAM ON VIEW). A view stream supports projections, WHERE filters, andUNION ALLover single-table branches —SELECT ... FROM t [WHERE ...] [UNION ALL SELECT ... FROM t2 [WHERE ...]] .... PlainUNION(which deduplicates), joins, GROUP BY/HAVING/QUALIFY, DISTINCT, LIMIT, CTEs, and subquery sources are rejected, matching Snowflake's change-tracking restrictions. Returns one bare (upper-case) base table name per branch — the names change capture matches on. -
resolveViewStreamBaseTable
Back-compat single-table resolver: the first (often only) branch's base table. -
executeCtasSourceSelect
Execute the source SELECT of a CTAS in a stream-consuming context. Streams read are captured (CTAS has no transaction to register on) and consumed byconsumeCtasStreams()once the table is created. -
consumeCtasStreams
public void consumeCtasStreams()Advance the offset of streams read by the last CTAS source SELECT. Call only after the CTAS succeeds. -
resolveRelationShape
A relation's column list from its definition's SHAPE alone — no row is read and no value computed (seeRelationShapeOnly), which is how CREATE VIEW learns its columns: a value-time fault in the body is the reader's, not the creator's. -
resolveRelationColumns
public List<TableColumn> resolveRelationColumns(String definition, List<String> explicitColumnNames) -
resolveColumnInTables
public Object resolveColumnInTables(Row row, List<Table> tables, Map<String, Table> aliasToTable, String qualifiedName) Resolve a (possibly qualified) column reference against a multi-table row context — the alias-aware resolution used by JOIN evaluation, exposed for the AST evaluator so a parsed Expression can be evaluated directly over joined rows (e.g.a.id = b.idresolves each side to its own table). Delegates togetQualifiedColumnValueFromTables(dev.frostlake.storage.Row, java.util.List<dev.frostlake.metastore.model.Table>, java.util.Map<java.lang.String, dev.frostlake.metastore.model.Table>, java.lang.String); throws if the name is not a column of any table. -
resolveColumnInTables
public Object resolveColumnInTables(Row row, List<Table> tables, Map<String, Table> aliasToTable, String qualifiedName, int[] resolvedOffset) Resolve likeresolveColumnInTables(Row, List, Map, String), additionally reporting HOW the reference resolved throughresolvedOffset[0]: the flat row offset when the value came from the plain table-column scan (a fixed layout position the caller may cache for this context), left untouched when it resolved any other way (literal fallback, merged join key — per-row decisions that must re-run).
-