diff --git a/Makefile b/Makefile index 58d6a0d7..e8248b82 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ without_options: osx dot -Tpng $$sample_path/dag.dot -o $$sample_path/dag.png; \ alphacheck $$sample_path/dag.dot \ --json_schema_path ./samples/sample-schema.json \ - > $$sample_path/alphacheck_stdout.txt 2> $$sample_path/alphacheck_stderr.txt; \ + > $$sample_path/alphacheck_stdout.txt 2> $$sample_path/alphacheck_stderr.txt || echo alphacheck $$sample_path failed; \ done; .PHONY: with_functions diff --git a/alphasql/BUILD b/alphasql/BUILD index a05a751a..d2413720 100644 --- a/alphasql/BUILD +++ b/alphasql/BUILD @@ -47,10 +47,19 @@ cc_library( ], ) +cc_library( + name = "common_lib", + hdrs = ["common_lib.h"], + deps = [ + "@com_google_zetasql//zetasql/parser:parser", + ], +) + cc_library( name = "table_name_resolver", hdrs = ["table_name_resolver.h"], deps = [ + ":common_lib", "@com_google_zetasql//zetasql/public:simple_catalog", "@com_google_zetasql//zetasql/public:type", "@boost//:property_tree", @@ -65,6 +74,7 @@ cc_binary( ], deps = [ ":json_schema_reader", + ":common_lib", "@com_google_zetasql//zetasql/base", "@com_google_zetasql//zetasql/base:map_util", "@com_google_zetasql//zetasql/base:ret_check", diff --git a/alphasql/alphacheck.cc b/alphasql/alphacheck.cc index 537d4e4a..0e232d0a 100644 --- a/alphasql/alphacheck.cc +++ b/alphasql/alphacheck.cc @@ -33,6 +33,7 @@ #include "zetasql/base/logging.h" #include "zetasql/public/analyzer.h" #include "zetasql/public/catalog.h" +#include "zetasql/public/error_helpers.h" #include "zetasql/public/evaluator.h" #include "zetasql/public/evaluator_table_iterator.h" #include "zetasql/public/language_options.h" @@ -42,6 +43,7 @@ #include "zetasql/public/value.h" #include "zetasql/resolved_ast/resolved_ast.h" +#include "alphasql/common_lib.h" #include "alphasql/json_schema_reader.h" #include "boost/graph/graphviz.hpp" #include "zetasql/base/status.h" @@ -122,6 +124,92 @@ SimpleCatalog *ConstructCatalog(const google::protobuf::DescriptorPool *pool, return catalog; } +absl::Status check(const std::string &sql, const ASTStatement *statement, + std::vector *temp_function_names, + std::vector *temp_table_names, + const AnalyzerOptions &options, SimpleCatalog *catalog) { + std::unique_ptr output; + + if (statement->node_kind() == AST_BEGIN_END_BLOCK) { + const ASTBeginEndBlock *stmt = statement->GetAs(); + for (const auto &body : stmt->statement_list_node()->statement_list()) { + ZETASQL_RETURN_IF_ERROR(check(sql, body, temp_function_names, + temp_table_names, options, catalog)); + } + if (stmt->handler_list() == nullptr) { + return absl::OkStatus(); + } + for (const ASTExceptionHandler *handler : + stmt->handler_list()->exception_handler_list()) { + auto exception_handlers = handler->statement_list()->statement_list(); + for (const auto &handler : exception_handlers) { + ZETASQL_RETURN_IF_ERROR(check(sql, handler, temp_function_names, + temp_table_names, options, catalog)); + } + } + return absl::OkStatus(); + } + ZETASQL_RETURN_IF_ERROR(AnalyzeStatementFromParserAST( + *statement, options, sql, catalog, catalog->type_factory(), &output)); + auto resolved_statement = output->resolved_statement(); + switch (resolved_statement->node_kind()) { + case RESOLVED_CREATE_TABLE_STMT: + case RESOLVED_CREATE_TABLE_AS_SELECT_STMT: { + auto *create_table_stmt = + resolved_statement->GetAs(); + std::cout << "DDL analyzed, adding table to catalog..." << std::endl; + std::string table_name = absl::StrJoin(create_table_stmt->name_path(), "."); + std::unique_ptr table( + new zetasql::SimpleTable(table_name)); + for (const auto &column_definition : + create_table_stmt->column_definition_list()) { + std::unique_ptr column(new SimpleColumn( + table_name, column_definition->column().name_id().ToString(), + catalog->type_factory()->MakeSimpleType( + column_definition->column().type()->kind()))); + ZETASQL_RETURN_IF_ERROR(table->AddColumn(column.release(), false)); + } + catalog->AddOwnedTable(table.release()); + if (create_table_stmt->create_scope() == + ResolvedCreateStatement::CREATE_TEMP) { + temp_table_names->push_back(table_name); + } + break; + } + case RESOLVED_CREATE_FUNCTION_STMT: { + auto *create_function_stmt = + resolved_statement->GetAs(); + std::cout + << "Create Function Statement analyzed, adding function to catalog..." + << std::endl; + std::string function_name = + absl::StrJoin(create_function_stmt->name_path(), "."); + Function *function = new Function(function_name, "group", Function::SCALAR); + function->AddSignature(create_function_stmt->signature()); + catalog->AddOwnedFunction(function); + if (create_function_stmt->create_scope() == + ResolvedCreateStatement::CREATE_TEMP) { + temp_function_names->push_back(function_name); + } + break; + } + case RESOLVED_DROP_STMT: { + auto *drop_stmt = resolved_statement->GetAs(); + std::cout << "Drop Statement analyzed, dropping table from catalog..." + << std::endl; + std::string table_name = absl::StrJoin(drop_stmt->name_path(), "."); + if (drop_stmt->is_if_exists()) { + zetasql::dropOwnedTableIfExists(catalog, table_name); + } else { + zetasql::dropOwnedTable(catalog, table_name); + } + break; + } + } + + return absl::OkStatus(); +} + // Runs the tool. absl::Status Run(const std::string &sql_file_path, const AnalyzerOptions &options, SimpleCatalog *catalog) { @@ -130,76 +218,98 @@ absl::Status Run(const std::string &sql_file_path, std::ifstream file(file_path, std::ios::in); std::string sql(std::istreambuf_iterator(file), {}); - TypeFactory factory; - ParseResumeLocation location = - ParseResumeLocation::FromStringView(sql_file_path, sql); - bool at_end_of_input = false; - std::unique_ptr output; - std::vector temp_function_names; std::vector temp_table_names; - while (!at_end_of_input) { - ZETASQL_RETURN_IF_ERROR(AnalyzeNextStatement( - &location, options, catalog, &factory, &output, &at_end_of_input)); - auto resolved_statement = output->resolved_statement(); - switch (resolved_statement->node_kind()) { - case RESOLVED_CREATE_TABLE_STMT: - case RESOLVED_CREATE_TABLE_AS_SELECT_STMT: { - auto *create_table_stmt = - resolved_statement->GetAs(); - std::cout << "DDL analyzed, adding table to catalog..." << std::endl; - std::string table_name = - absl::StrJoin(create_table_stmt->name_path(), "."); - std::unique_ptr table( - new zetasql::SimpleTable(table_name)); - for (const auto &column_definition : - create_table_stmt->column_definition_list()) { - std::unique_ptr column(new SimpleColumn( - table_name, column_definition->column().name_id().ToString(), - catalog->type_factory()->MakeSimpleType( - column_definition->column().type()->kind()))); - ZETASQL_RETURN_IF_ERROR(table->AddColumn(column.release(), false)); - } - catalog->AddOwnedTable(table.release()); - if (create_table_stmt->create_scope() == - ResolvedCreateStatement::CREATE_TEMP) { - temp_table_names.push_back(table_name); - } - break; - } - case RESOLVED_CREATE_FUNCTION_STMT: { - auto *create_function_stmt = - resolved_statement->GetAs(); - std::cout - << "Create Function Statement analyzed, adding function to catalog..." - << std::endl; - std::string function_name = - absl::StrJoin(create_function_stmt->name_path(), "."); - Function *function = - new Function(function_name, "group", Function::SCALAR); - function->AddSignature(create_function_stmt->signature()); - catalog->AddOwnedFunction(function); - if (create_function_stmt->create_scope() == - ResolvedCreateStatement::CREATE_TEMP) { - temp_function_names.push_back(function_name); - } - break; - } - case RESOLVED_DROP_STMT: { - auto *drop_stmt = resolved_statement->GetAs(); - std::cout << "Drop Statement analyzed, dropping table from catalog..." - << std::endl; - std::string table_name = absl::StrJoin(drop_stmt->name_path(), "."); - if (drop_stmt->is_if_exists()) { - zetasql::dropOwnedTableIfExists(catalog, table_name); - } else { - zetasql::dropOwnedTable(catalog, table_name); - } - break; - } - } + std::unique_ptr parser_output; + ZETASQL_RETURN_IF_ERROR(alphasql::ParseScript(sql, options.GetParserOptions(), + options.error_message_mode(), + &parser_output, file_path)); + + auto statements = + parser_output->script()->statement_list_node()->statement_list(); + for (const ASTStatement *statement : statements) { + ZETASQL_RETURN_IF_ERROR(check(sql, statement, &temp_function_names, + &temp_table_names, options, catalog)); } + /* for (const ASTStatement *statement : statements) { */ + /* if (statement->node_kind() == AST_BEGIN_END_BLOCK) { */ + /* const ASTBeginEndBlock *stmt = statement->GetAs(); */ + /* auto body = stmt->statement_list_node()->statement_list(); */ + /* statements.insert(statements.end(), body.begin(), body.end()); */ + /* for (const ASTExceptionHandler *handler : */ + /* stmt->handler_list()->exception_handler_list()) { */ + /* auto exception_handlers = + * handler->statement_list()->statement_list(); */ + /* statements.insert(statements.end(), exception_handlers.begin(), + * exception_handlers.end()); */ + /* } */ + /* continue; */ + /* } */ + /* ZETASQL_RETURN_IF_ERROR(AnalyzeStatementFromParserAST( */ + /* *statement, options, sql, catalog, &factory, &output)); */ + /* auto resolved_statement = output->resolved_statement(); */ + /* switch (resolved_statement->node_kind()) { */ + /* case RESOLVED_CREATE_TABLE_STMT: */ + /* case RESOLVED_CREATE_TABLE_AS_SELECT_STMT: { */ + /* auto *create_table_stmt = */ + /* resolved_statement->GetAs(); */ + /* std::cout << "DDL analyzed, adding table to catalog..." << std::endl; + */ + /* std::string table_name = */ + /* absl::StrJoin(create_table_stmt->name_path(), "."); */ + /* std::unique_ptr table( */ + /* new zetasql::SimpleTable(table_name)); */ + /* for (const auto &column_definition : */ + /* create_table_stmt->column_definition_list()) { */ + /* std::unique_ptr column(new SimpleColumn( */ + /* table_name, column_definition->column().name_id().ToString(), */ + /* catalog->type_factory()->MakeSimpleType( */ + /* column_definition->column().type()->kind()))); */ + /* ZETASQL_RETURN_IF_ERROR(table->AddColumn(column.release(), false)); + */ + /* } */ + /* catalog->AddOwnedTable(table.release()); */ + /* if (create_table_stmt->create_scope() == */ + /* ResolvedCreateStatement::CREATE_TEMP) { */ + /* temp_table_names.push_back(table_name); */ + /* } */ + /* break; */ + /* } */ + /* case RESOLVED_CREATE_FUNCTION_STMT: { */ + /* auto *create_function_stmt = */ + /* resolved_statement->GetAs(); */ + /* std::cout */ + /* << "Create Function Statement analyzed, adding function to + * catalog..." */ + /* << std::endl; */ + /* std::string function_name = */ + /* absl::StrJoin(create_function_stmt->name_path(), "."); */ + /* Function *function = */ + /* new Function(function_name, "group", Function::SCALAR); */ + /* function->AddSignature(create_function_stmt->signature()); */ + /* catalog->AddOwnedFunction(function); */ + /* if (create_function_stmt->create_scope() == */ + /* ResolvedCreateStatement::CREATE_TEMP) { */ + /* temp_function_names.push_back(function_name); */ + /* } */ + /* break; */ + /* } */ + /* case RESOLVED_DROP_STMT: { */ + /* auto *drop_stmt = resolved_statement->GetAs(); */ + /* std::cout << "Drop Statement analyzed, dropping table from catalog..." + */ + /* << std::endl; */ + /* std::string table_name = absl::StrJoin(drop_stmt->name_path(), "."); */ + /* if (drop_stmt->is_if_exists()) { */ + /* zetasql::dropOwnedTableIfExists(catalog, table_name); */ + /* } else { */ + /* zetasql::dropOwnedTable(catalog, table_name); */ + /* } */ + /* break; */ + /* } */ + /* } */ + /* } */ for (const auto &table_name : temp_table_names) { std::cout << "Removing temporary table " << table_name << std::endl; @@ -279,10 +389,12 @@ int main(int argc, char *argv[]) { std::cout << "ERROR: not a file " << sql_file_path << std::endl; return 1; } - const absl::Status status = alphasql::Run(sql_file_path, options, catalog); + absl::Status status = alphasql::Run(sql_file_path, options, catalog); if (status.ok()) { std::cout << "SUCCESS: analysis finished!" << std::endl; } else { + status = zetasql::UpdateErrorLocationPayloadWithFilenameIfNotPresent( + status, sql_file_path); std::cout << "ERROR: " << status << std::endl; std::cout << "catalog:" << std::endl; for (const std::string &table_name : catalog->table_names()) { diff --git a/alphasql/common_lib.h b/alphasql/common_lib.h new file mode 100644 index 00000000..e5525466 --- /dev/null +++ b/alphasql/common_lib.h @@ -0,0 +1,61 @@ +// +// Copyright 2020 Matts966 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "zetasql/parser/bison_parser.h" +#include "zetasql/parser/bison_parser_mode.h" +#include "zetasql/parser/parse_tree.h" +#include "zetasql/parser/parser.h" + +namespace alphasql { + +using namespace zetasql; +using namespace zetasql::parser; +using zetasql::parser::BisonParser; +using zetasql::parser::BisonParserMode; + +absl::Status ParseScript(absl::string_view script_string, + const ParserOptions &parser_options_in, + ErrorMessageMode error_message_mode, + std::unique_ptr *output, + const std::string &filename) { + ParserOptions parser_options = parser_options_in; + parser_options.CreateDefaultArenasIfNotSet(); + + BisonParser parser; + std::unique_ptr ast_node; + std::vector> other_allocated_ast_nodes; + absl::Status status = parser.Parse( + BisonParserMode::kScript, filename, script_string, + /*start_byte_offset=*/0, parser_options.id_string_pool().get(), + parser_options.arena().get(), parser_options.language_options(), + &ast_node, &other_allocated_ast_nodes, + /*ast_statement_properties=*/nullptr, + /*statement_end_byte_offset=*/nullptr); + + std::unique_ptr script; + if (status.ok()) { + ZETASQL_RET_CHECK_EQ(ast_node->node_kind(), AST_SCRIPT); + script = absl::WrapUnique(ast_node.release()->GetAsOrDie()); + } + ZETASQL_RETURN_IF_ERROR(ConvertInternalErrorLocationAndAdjustErrorString( + error_message_mode, script_string, status)); + *output = absl::make_unique( + parser_options.id_string_pool(), parser_options.arena(), + std::move(other_allocated_ast_nodes), std::move(script)); + return absl::OkStatus(); +} + +} // namespace alphasql diff --git a/alphasql/identifier_resolver.cc b/alphasql/identifier_resolver.cc index e6c29579..a7eb99a6 100644 --- a/alphasql/identifier_resolver.cc +++ b/alphasql/identifier_resolver.cc @@ -73,16 +73,12 @@ GetIdentifierInformation(const std::string &sql_file_path) { std::ifstream file(file_path, std::ios::in); std::string sql(std::istreambuf_iterator(file), {}); - ZETASQL_RETURN_IF_ERROR(ParseScript(sql, options.GetParserOptions(), - options.error_message_mode(), - &parser_output)); + ZETASQL_RETURN_IF_ERROR(alphasql::ParseScript(sql, options.GetParserOptions(), + options.error_message_mode(), + &parser_output, file_path)); + IdentifierResolver resolver = IdentifierResolver(); parser_output->script()->Accept(&resolver, nullptr); - // TODO: The below function call is not OK compared to GetTables, but more - // performant. Try to fix bugs and use FindTableNamesInScript. - // ZETASQL_RETURN_IF_ERROR(alphasql::table_name_resolver::FindTableNamesInScript(sql, - // *parser_output->script(), options, - // &resolver.identifier_information.table_information.referenced)); table_name_resolver::GetTables( sql_file_path, options, &resolver.identifier_information.table_information.referenced); diff --git a/alphasql/table_name_resolver.h b/alphasql/table_name_resolver.h index 3f6d4c08..112b4d81 100644 --- a/alphasql/table_name_resolver.h +++ b/alphasql/table_name_resolver.h @@ -25,6 +25,8 @@ #include "zetasql/resolved_ast/resolved_ast.h" #include "zetasql/resolved_ast/resolved_node_kind.pb.h" +#include "alphasql/common_lib.h" + // TODO This implementation probably doesn't cover all edge cases for // table name extraction. It should be tested more and tuned for the final // name scoping rules once those are implemented in the full resolver. @@ -654,6 +656,26 @@ absl::Status TableNameResolver::FindInStatement(const ASTStatement *statement) { return FindInExpressionsUnder(stmt->sql(), /*visible_aliases=*/{}); } break; + + // Diffs + case AST_BEGIN_END_BLOCK: { + const ASTBeginEndBlock *stmt = statement->GetAs(); + for (const ASTStatement *statement : + stmt->statement_list_node()->statement_list()) { + ZETASQL_RETURN_IF_ERROR(FindInStatement(statement)); + } + if (stmt->handler_list() != nullptr) { + for (const ASTExceptionHandler *handler : + stmt->handler_list()->exception_handler_list()) { + for (const ASTStatement *statement : + handler->statement_list()->statement_list()) { + ZETASQL_RETURN_IF_ERROR(FindInStatement(statement)); + } + } + } + return absl::OkStatus(); + } + default: break; } @@ -855,8 +877,8 @@ absl::Status TableNameResolver::FindInQuery(const ASTQuery *query, absl::AsciiStrToLower(with_entry->alias()->GetAsString()); } } else { - // In WITH without RECURSIVE, entries can only access with aliases defined - // in prior entries. + // In WITH without RECURSIVE, entries can only access with aliases + // defined in prior entries. for (const ASTWithClauseEntry *with_entry : query->with_clause()->with()) { ZETASQL_RETURN_IF_ERROR( @@ -1001,12 +1023,12 @@ absl::Status TableNameResolver::FindInTVF(const ASTTVF *tvf, const AliasSet &external_visible_aliases, AliasSet *local_visible_aliases) { - // The 'tvf' here is the TVF parse node. Each TVF argument may be a scalar, a - // relation, or a TABLE clause. We've parsed all of the TVF arguments as - // expressions by this point, so the FindInExpressionsUnder call will descend - // into the relation arguments as expression subqueries. For TABLE clause - // arguments, we add each named table to the set of referenced table names in - // a separate step. + // The 'tvf' here is the TVF parse node. Each TVF argument may be a scalar, + // a relation, or a TABLE clause. We've parsed all of the TVF arguments as + // expressions by this point, so the FindInExpressionsUnder call will + // descend into the relation arguments as expression subqueries. For TABLE + // clause arguments, we add each named table to the set of referenced table + // names in a separate step. // // Note about correlation: if a TVF argument is a scalar, it should resolve // like a correlated subquery and be able to see 'local_visible_aliases'. On @@ -1078,9 +1100,9 @@ absl::Status TableNameResolver::FindInTablePathExpression( std::vector path = path_expr->ToIdentifierVector(); ZETASQL_RET_CHECK(!path.empty()); - // Single identifiers are always table names, not range variable references, - // but could be WITH table references or references to TVF arguments that - // should be ignored. + // Single identifiers are always table names, not range variable + // references, but could be WITH table references or references to TVF + // arguments that should be ignored. // // For paths, check if the first identifier is a known alias. This allows // us to ignore correlated alias references like: @@ -1192,33 +1214,19 @@ absl::Status GetTables(const std::string &sql_file_path, const AnalyzerOptions &analyzer_options, TableNamesSet *table_names) { std::unique_ptr parser_output; - std::filesystem::path file_path(sql_file_path); std::ifstream file(file_path, std::ios::in); std::string sql(std::istreambuf_iterator(file), {}); - - ParseResumeLocation location = - ParseResumeLocation::FromStringView(sql_file_path, sql); - bool at_end_of_input = false; + ZETASQL_RETURN_IF_ERROR(alphasql::ParseScript( + sql, analyzer_options.GetParserOptions(), + analyzer_options.error_message_mode(), &parser_output, file_path)); auto resolver = alphasql::table_name_resolver::TableNameResolver( sql, &analyzer_options, nullptr, nullptr, table_names, nullptr); - while (!at_end_of_input) { - auto status = - ParseNextStatement(&location, analyzer_options.GetParserOptions(), - &parser_output, &at_end_of_input); - - if (parser_output == nullptr) { - return ConvertInternalErrorLocationAndAdjustErrorString( - analyzer_options.error_message_mode(), sql, status); - } - - status = resolver.FindInStatement(parser_output->statement()); - if (!status.ok()) { - return ConvertInternalErrorLocationAndAdjustErrorString( - analyzer_options.error_message_mode(), sql, status); - } + auto statements = parser_output->script()->statement_list_node(); + for (const ASTStatement *statement : statements->statement_list()) { + ZETASQL_RETURN_IF_ERROR(resolver.FindInStatement(statement)); } return absl::OkStatus(); diff --git a/samples/scripting/alphacheck_stderr.txt b/samples/scripting/alphacheck_stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/samples/scripting/alphacheck_stdout.txt b/samples/scripting/alphacheck_stdout.txt new file mode 100644 index 00000000..8010f56c --- /dev/null +++ b/samples/scripting/alphacheck_stdout.txt @@ -0,0 +1,10 @@ +Analyzing "samples/scripting/script.sql" +DDL analyzed, adding table to catalog... +DDL analyzed, adding table to catalog... +ERROR: INVALID_ARGUMENT: Procedure not found: create_datawarehouse3 [at samples/scripting/script.sql:12:8] +catalog: + tablename2 + tablename1 + dataset.main + datawarehouse2 + datawarehouse1 diff --git a/samples/scripting/alphadag_stderr.txt b/samples/scripting/alphadag_stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/samples/scripting/alphadag_stdout.txt b/samples/scripting/alphadag_stdout.txt new file mode 100644 index 00000000..bfb3dbaa --- /dev/null +++ b/samples/scripting/alphadag_stdout.txt @@ -0,0 +1,5 @@ +Reading paths passed as a command line arguments... +Only files that end with .sql or .bq are analyzed. +Reading "samples/scripting/procedure.sql" +Reading "samples/scripting/script.sql" +Reading "samples/scripting/mart.sql" diff --git a/samples/scripting/dag.dot b/samples/scripting/dag.dot new file mode 100644 index 00000000..8e7387c4 --- /dev/null +++ b/samples/scripting/dag.dot @@ -0,0 +1,6 @@ +digraph G { +0 [label="samples/scripting/mart.sql", shape="", type=query]; +1 [label="samples/scripting/procedure.sql", shape="", type=query]; +2 [label="samples/scripting/script.sql", shape="", type=query]; +2->0 ; +} diff --git a/samples/scripting/dag.png b/samples/scripting/dag.png new file mode 100644 index 00000000..c332d479 Binary files /dev/null and b/samples/scripting/dag.png differ diff --git a/samples/scripting/external_tables.txt b/samples/scripting/external_tables.txt new file mode 100644 index 00000000..d6551a6a --- /dev/null +++ b/samples/scripting/external_tables.txt @@ -0,0 +1,3 @@ +tablename1 +tablename2 +tmp diff --git a/samples/scripting/mart.sql b/samples/scripting/mart.sql new file mode 100644 index 00000000..d6663e88 --- /dev/null +++ b/samples/scripting/mart.sql @@ -0,0 +1,19 @@ +BEGIN TRANSACTION; + +CREATE TEMP TABLE tmp AS +SELECT * FROM datawarehouse1 +UNION ALL +SELECT * FROM datawarehouse2 +UNION ALL +SELECT * FROM datawarehouse3; + +DROP TABLE IF EXISTS `datawarehouse1`; +DROP TABLE IF EXISTS `datawarehouse2`; +DROP TABLE IF EXISTS `datawarehouse1`; + +CREATE OR REPLACE TABLE mart AS +SELECT * FROM tmp; + +DROP TABLE tmp; + +COMMIT TRANSACTION; diff --git a/samples/scripting/procedure.sql b/samples/scripting/procedure.sql new file mode 100644 index 00000000..db969e59 --- /dev/null +++ b/samples/scripting/procedure.sql @@ -0,0 +1,8 @@ +CREATE OR REPLACE PROCEDURE create_datawarehouse3() +BEGIN + CREATE OR REPLACE TABLE datawarehouse3 AS + SELECT + x + FROM + dataset.main; +END diff --git a/samples/scripting/script.sql b/samples/scripting/script.sql new file mode 100644 index 00000000..8ed2f8b3 --- /dev/null +++ b/samples/scripting/script.sql @@ -0,0 +1,13 @@ +BEGIN + CREATE OR REPLACE TABLE datawarehouse2 AS + SELECT + column1 AS x + FROM + tablename1; + CREATE OR REPLACE TABLE datawarehouse1 AS + SELECT + column2 AS x + FROM + tablename2; + CALL create_datawarehouse3(); +END diff --git a/samples/scripting/side_effect_first/alphadag_stderr.txt b/samples/scripting/side_effect_first/alphadag_stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/samples/scripting/side_effect_first/alphadag_stdout.txt b/samples/scripting/side_effect_first/alphadag_stdout.txt new file mode 100644 index 00000000..bfb3dbaa --- /dev/null +++ b/samples/scripting/side_effect_first/alphadag_stdout.txt @@ -0,0 +1,5 @@ +Reading paths passed as a command line arguments... +Only files that end with .sql or .bq are analyzed. +Reading "samples/scripting/procedure.sql" +Reading "samples/scripting/script.sql" +Reading "samples/scripting/mart.sql" diff --git a/samples/scripting/side_effect_first/dag.dot b/samples/scripting/side_effect_first/dag.dot new file mode 100644 index 00000000..8e7387c4 --- /dev/null +++ b/samples/scripting/side_effect_first/dag.dot @@ -0,0 +1,6 @@ +digraph G { +0 [label="samples/scripting/mart.sql", shape="", type=query]; +1 [label="samples/scripting/procedure.sql", shape="", type=query]; +2 [label="samples/scripting/script.sql", shape="", type=query]; +2->0 ; +} diff --git a/samples/scripting/side_effect_first/dag.png b/samples/scripting/side_effect_first/dag.png new file mode 100644 index 00000000..c332d479 Binary files /dev/null and b/samples/scripting/side_effect_first/dag.png differ diff --git a/samples/scripting/side_effect_first/external_tables.txt b/samples/scripting/side_effect_first/external_tables.txt new file mode 100644 index 00000000..d6551a6a --- /dev/null +++ b/samples/scripting/side_effect_first/external_tables.txt @@ -0,0 +1,3 @@ +tablename1 +tablename2 +tmp diff --git a/samples/scripting/side_effect_first_with_tables/alphadag_stderr.txt b/samples/scripting/side_effect_first_with_tables/alphadag_stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/samples/scripting/side_effect_first_with_tables/alphadag_stdout.txt b/samples/scripting/side_effect_first_with_tables/alphadag_stdout.txt new file mode 100644 index 00000000..bfb3dbaa --- /dev/null +++ b/samples/scripting/side_effect_first_with_tables/alphadag_stdout.txt @@ -0,0 +1,5 @@ +Reading paths passed as a command line arguments... +Only files that end with .sql or .bq are analyzed. +Reading "samples/scripting/procedure.sql" +Reading "samples/scripting/script.sql" +Reading "samples/scripting/mart.sql" diff --git a/samples/scripting/side_effect_first_with_tables/dag.dot b/samples/scripting/side_effect_first_with_tables/dag.dot new file mode 100644 index 00000000..4be4249b --- /dev/null +++ b/samples/scripting/side_effect_first_with_tables/dag.dot @@ -0,0 +1,21 @@ +digraph G { +0 [label="samples/scripting/mart.sql", shape="", type=query]; +1 [label="samples/scripting/procedure.sql", shape="", type=query]; +2 [label="samples/scripting/script.sql", shape="", type=query]; +3 [label=datawarehouse1, shape=box, type=table]; +4 [label=datawarehouse2, shape=box, type=table]; +5 [label=datawarehouse3, shape=box, type=table]; +6 [label=mart, shape=box, type=table]; +7 [label=tablename1, shape=box, type=table]; +8 [label=tablename2, shape=box, type=table]; +9 [label=tmp, shape=box, type=table]; +0->6 ; +1->5 ; +2->3 ; +2->4 ; +3->0 ; +4->0 ; +7->2 ; +8->2 ; +9->0 ; +} diff --git a/samples/scripting/side_effect_first_with_tables/dag.png b/samples/scripting/side_effect_first_with_tables/dag.png new file mode 100644 index 00000000..d0c02748 Binary files /dev/null and b/samples/scripting/side_effect_first_with_tables/dag.png differ diff --git a/samples/scripting/side_effect_first_with_tables/external_tables.txt b/samples/scripting/side_effect_first_with_tables/external_tables.txt new file mode 100644 index 00000000..d6551a6a --- /dev/null +++ b/samples/scripting/side_effect_first_with_tables/external_tables.txt @@ -0,0 +1,3 @@ +tablename1 +tablename2 +tmp diff --git a/samples/scripting/with_all/alphadag_stderr.txt b/samples/scripting/with_all/alphadag_stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/samples/scripting/with_all/alphadag_stdout.txt b/samples/scripting/with_all/alphadag_stdout.txt new file mode 100644 index 00000000..bfb3dbaa --- /dev/null +++ b/samples/scripting/with_all/alphadag_stdout.txt @@ -0,0 +1,5 @@ +Reading paths passed as a command line arguments... +Only files that end with .sql or .bq are analyzed. +Reading "samples/scripting/procedure.sql" +Reading "samples/scripting/script.sql" +Reading "samples/scripting/mart.sql" diff --git a/samples/scripting/with_all/dag.dot b/samples/scripting/with_all/dag.dot new file mode 100644 index 00000000..4be4249b --- /dev/null +++ b/samples/scripting/with_all/dag.dot @@ -0,0 +1,21 @@ +digraph G { +0 [label="samples/scripting/mart.sql", shape="", type=query]; +1 [label="samples/scripting/procedure.sql", shape="", type=query]; +2 [label="samples/scripting/script.sql", shape="", type=query]; +3 [label=datawarehouse1, shape=box, type=table]; +4 [label=datawarehouse2, shape=box, type=table]; +5 [label=datawarehouse3, shape=box, type=table]; +6 [label=mart, shape=box, type=table]; +7 [label=tablename1, shape=box, type=table]; +8 [label=tablename2, shape=box, type=table]; +9 [label=tmp, shape=box, type=table]; +0->6 ; +1->5 ; +2->3 ; +2->4 ; +3->0 ; +4->0 ; +7->2 ; +8->2 ; +9->0 ; +} diff --git a/samples/scripting/with_all/dag.png b/samples/scripting/with_all/dag.png new file mode 100644 index 00000000..d0c02748 Binary files /dev/null and b/samples/scripting/with_all/dag.png differ diff --git a/samples/scripting/with_all/external_tables.txt b/samples/scripting/with_all/external_tables.txt new file mode 100644 index 00000000..d6551a6a --- /dev/null +++ b/samples/scripting/with_all/external_tables.txt @@ -0,0 +1,3 @@ +tablename1 +tablename2 +tmp diff --git a/samples/scripting/with_functions/alphadag_stderr.txt b/samples/scripting/with_functions/alphadag_stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/samples/scripting/with_functions/alphadag_stdout.txt b/samples/scripting/with_functions/alphadag_stdout.txt new file mode 100644 index 00000000..bfb3dbaa --- /dev/null +++ b/samples/scripting/with_functions/alphadag_stdout.txt @@ -0,0 +1,5 @@ +Reading paths passed as a command line arguments... +Only files that end with .sql or .bq are analyzed. +Reading "samples/scripting/procedure.sql" +Reading "samples/scripting/script.sql" +Reading "samples/scripting/mart.sql" diff --git a/samples/scripting/with_functions/dag.dot b/samples/scripting/with_functions/dag.dot new file mode 100644 index 00000000..8e7387c4 --- /dev/null +++ b/samples/scripting/with_functions/dag.dot @@ -0,0 +1,6 @@ +digraph G { +0 [label="samples/scripting/mart.sql", shape="", type=query]; +1 [label="samples/scripting/procedure.sql", shape="", type=query]; +2 [label="samples/scripting/script.sql", shape="", type=query]; +2->0 ; +} diff --git a/samples/scripting/with_functions/dag.png b/samples/scripting/with_functions/dag.png new file mode 100644 index 00000000..c332d479 Binary files /dev/null and b/samples/scripting/with_functions/dag.png differ diff --git a/samples/scripting/with_functions/external_tables.txt b/samples/scripting/with_functions/external_tables.txt new file mode 100644 index 00000000..d6551a6a --- /dev/null +++ b/samples/scripting/with_functions/external_tables.txt @@ -0,0 +1,3 @@ +tablename1 +tablename2 +tmp diff --git a/samples/scripting/with_tables/alphadag_stderr.txt b/samples/scripting/with_tables/alphadag_stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/samples/scripting/with_tables/alphadag_stdout.txt b/samples/scripting/with_tables/alphadag_stdout.txt new file mode 100644 index 00000000..bfb3dbaa --- /dev/null +++ b/samples/scripting/with_tables/alphadag_stdout.txt @@ -0,0 +1,5 @@ +Reading paths passed as a command line arguments... +Only files that end with .sql or .bq are analyzed. +Reading "samples/scripting/procedure.sql" +Reading "samples/scripting/script.sql" +Reading "samples/scripting/mart.sql" diff --git a/samples/scripting/with_tables/dag.dot b/samples/scripting/with_tables/dag.dot new file mode 100644 index 00000000..4be4249b --- /dev/null +++ b/samples/scripting/with_tables/dag.dot @@ -0,0 +1,21 @@ +digraph G { +0 [label="samples/scripting/mart.sql", shape="", type=query]; +1 [label="samples/scripting/procedure.sql", shape="", type=query]; +2 [label="samples/scripting/script.sql", shape="", type=query]; +3 [label=datawarehouse1, shape=box, type=table]; +4 [label=datawarehouse2, shape=box, type=table]; +5 [label=datawarehouse3, shape=box, type=table]; +6 [label=mart, shape=box, type=table]; +7 [label=tablename1, shape=box, type=table]; +8 [label=tablename2, shape=box, type=table]; +9 [label=tmp, shape=box, type=table]; +0->6 ; +1->5 ; +2->3 ; +2->4 ; +3->0 ; +4->0 ; +7->2 ; +8->2 ; +9->0 ; +} diff --git a/samples/scripting/with_tables/dag.png b/samples/scripting/with_tables/dag.png new file mode 100644 index 00000000..d0c02748 Binary files /dev/null and b/samples/scripting/with_tables/dag.png differ diff --git a/samples/scripting/with_tables/external_tables.txt b/samples/scripting/with_tables/external_tables.txt new file mode 100644 index 00000000..d6551a6a --- /dev/null +++ b/samples/scripting/with_tables/external_tables.txt @@ -0,0 +1,3 @@ +tablename1 +tablename2 +tmp