mirror of
https://github.com/temporalio/temporal.git
synced 2026-08-30 18:41:49 -07:00
Remove support for standard visibility (#5387)
## What changed? <!-- Describe what has changed in this PR --> Remove support for standard visibility ## Why? <!-- Tell your future self why have you made these changes --> Standard visibility is deprecated. ## How did you test it? <!-- How have you verified this change? Tested locally? Added a unit test? Checked in staging env? --> ## Potential risks <!-- Assuming the worst case, what can be broken when deploying this change to production? --> ## Is hotfix candidate? <!-- Is this PR a hotfix candidate or does it require a notification to be sent to the broader community? (Yes/No) -->
This commit is contained in:
42
.github/workflows/run-tests.yml
vendored
42
.github/workflows/run-tests.yml
vendored
@@ -133,7 +133,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runs-on: [ubuntu-latest]
|
||||
name: [cass_es, cass_es8, sqlite, mysql, mysql8, postgres, postgres_pgx, postgres12, postgres12_pgx]
|
||||
name: [cass_es, cass_es8, sqlite, mysql8, postgres12, postgres12_pgx]
|
||||
shard_index: [0, 1, 2]
|
||||
include:
|
||||
- name: cass_es
|
||||
@@ -148,22 +148,10 @@ jobs:
|
||||
persistence_type: sql
|
||||
persistence_driver: sqlite
|
||||
containers: []
|
||||
- name: mysql
|
||||
persistence_type: sql
|
||||
persistence_driver: mysql
|
||||
containers: [mysql, elasticsearch]
|
||||
- name: mysql8
|
||||
persistence_type: sql
|
||||
persistence_driver: mysql8
|
||||
containers: [mysql]
|
||||
- name: postgres
|
||||
persistence_type: sql
|
||||
persistence_driver: postgres
|
||||
containers: [postgresql, elasticsearch]
|
||||
- name: postgres_pgx
|
||||
persistence_type: sql
|
||||
persistence_driver: postgres_pgx
|
||||
containers: [postgresql, elasticsearch]
|
||||
- name: postgres12
|
||||
persistence_type: sql
|
||||
persistence_driver: postgres12
|
||||
@@ -214,7 +202,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runs-on: [ubuntu-latest]
|
||||
name: [cass_es, cass_es8, mysql, mysql8, postgres, postgres_pgx, postgres12, postgres12_pgx]
|
||||
name: [cass_es, cass_es8, mysql8, postgres12, postgres12_pgx]
|
||||
include:
|
||||
- name: cass_es
|
||||
persistence_type: nosql
|
||||
@@ -224,22 +212,10 @@ jobs:
|
||||
persistence_type: nosql
|
||||
persistence_driver: elasticsearch
|
||||
containers: [cassandra, elasticsearch8]
|
||||
- name: mysql
|
||||
persistence_type: sql
|
||||
persistence_driver: mysql
|
||||
containers: [mysql, elasticsearch]
|
||||
- name: mysql8
|
||||
persistence_type: sql
|
||||
persistence_driver: mysql8
|
||||
containers: [mysql]
|
||||
- name: postgres
|
||||
persistence_type: sql
|
||||
persistence_driver: postgres12
|
||||
containers: [postgresql, elasticsearch]
|
||||
- name: postgres_pgx
|
||||
persistence_type: sql
|
||||
persistence_driver: postgres12_pgx
|
||||
containers: [postgresql, elasticsearch]
|
||||
- name: postgres12
|
||||
persistence_type: sql
|
||||
persistence_driver: postgres12
|
||||
@@ -288,7 +264,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runs-on: [ubuntu-latest]
|
||||
name: [cass_es, cass_es8, mysql, mysql8, postgres, postgres_pgx, postgres12, postgres12_pgx]
|
||||
name: [cass_es, cass_es8, mysql8, postgres12, postgres12_pgx]
|
||||
include:
|
||||
- name: cass_es
|
||||
persistence_type: nosql
|
||||
@@ -298,22 +274,10 @@ jobs:
|
||||
persistence_type: nosql
|
||||
persistence_driver: elasticsearch
|
||||
containers: [cassandra, elasticsearch8]
|
||||
- name: mysql
|
||||
persistence_type: sql
|
||||
persistence_driver: mysql
|
||||
containers: [mysql, elasticsearch]
|
||||
- name: mysql8
|
||||
persistence_type: sql
|
||||
persistence_driver: mysql8
|
||||
containers: [mysql]
|
||||
- name: postgres
|
||||
persistence_type: sql
|
||||
persistence_driver: postgres12
|
||||
containers: [postgresql, elasticsearch]
|
||||
- name: postgres_pgx
|
||||
persistence_type: sql
|
||||
persistence_driver: postgres12_pgx
|
||||
containers: [postgresql, elasticsearch]
|
||||
- name: postgres12
|
||||
persistence_type: sql
|
||||
persistence_driver: postgres12
|
||||
|
||||
60
Makefile
60
Makefile
@@ -396,49 +396,31 @@ install-schema-cass-es: temporal-cassandra-tool install-schema-es
|
||||
./temporal-cassandra-tool -k $(TEMPORAL_DB) setup-schema -v 0.0
|
||||
./temporal-cassandra-tool -k $(TEMPORAL_DB) update-schema -d ./schema/cassandra/temporal/versioned
|
||||
|
||||
install-schema-mysql: temporal-sql-tool
|
||||
@printf $(COLOR) "Install MySQL schema..."
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(TEMPORAL_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(TEMPORAL_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(TEMPORAL_DB) setup-schema -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(TEMPORAL_DB) update-schema -d ./schema/mysql/v57/temporal/versioned
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(VISIBILITY_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(VISIBILITY_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(VISIBILITY_DB) setup-schema -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(VISIBILITY_DB) update-schema -d ./schema/mysql/v57/visibility/versioned
|
||||
install-schema-mysql: install-schema-mysql8
|
||||
|
||||
install-schema-mysql8: temporal-sql-tool
|
||||
@printf $(COLOR) "Install MySQL schema..."
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(TEMPORAL_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(TEMPORAL_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(TEMPORAL_DB) setup-schema -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(TEMPORAL_DB) update-schema -d ./schema/mysql/v8/temporal/versioned
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(VISIBILITY_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(VISIBILITY_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(VISIBILITY_DB) setup-schema -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --db $(VISIBILITY_DB) update-schema -d ./schema/mysql/v8/visibility/versioned
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --pl mysql8 --db $(TEMPORAL_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --pl mysql8 --db $(TEMPORAL_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --pl mysql8 --db $(TEMPORAL_DB) setup-schema -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --pl mysql8 --db $(TEMPORAL_DB) update-schema -d ./schema/mysql/v8/temporal/versioned
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --pl mysql8 --db $(VISIBILITY_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --pl mysql8 --db $(VISIBILITY_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --pl mysql8 --db $(VISIBILITY_DB) setup-schema -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) --pl mysql8 --db $(VISIBILITY_DB) update-schema -d ./schema/mysql/v8/visibility/versioned
|
||||
|
||||
install-schema-postgresql: temporal-sql-tool
|
||||
@printf $(COLOR) "Install Postgres schema..."
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(TEMPORAL_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(TEMPORAL_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(TEMPORAL_DB) setup -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(TEMPORAL_DB) update-schema -d ./schema/postgresql/v96/temporal/versioned
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(VISIBILITY_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(VISIBILITY_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(VISIBILITY_DB) setup-schema -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(VISIBILITY_DB) update-schema -d ./schema/postgresql/v96/visibility/versioned
|
||||
install-schema-postgresql: install-schema-postgresql12
|
||||
|
||||
install-schema-postgresql12: temporal-sql-tool
|
||||
@printf $(COLOR) "Install Postgres schema..."
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(TEMPORAL_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(TEMPORAL_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(TEMPORAL_DB) setup -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(TEMPORAL_DB) update-schema -d ./schema/postgresql/v12/temporal/versioned
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(VISIBILITY_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(VISIBILITY_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(VISIBILITY_DB) setup-schema -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres --db $(VISIBILITY_DB) update-schema -d ./schema/postgresql/v12/visibility/versioned
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres12 --db $(TEMPORAL_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres12 --db $(TEMPORAL_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres12 --db $(TEMPORAL_DB) setup -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres12 --db $(TEMPORAL_DB) update-schema -d ./schema/postgresql/v12/temporal/versioned
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres12 --db $(VISIBILITY_DB) drop -f
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres12 --db $(VISIBILITY_DB) create
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres12 --db $(VISIBILITY_DB) setup-schema -v 0.0
|
||||
./temporal-sql-tool -u $(SQL_USER) --pw $(SQL_PASSWORD) -p 5432 --pl postgres12 --db $(VISIBILITY_DB) update-schema -d ./schema/postgresql/v12/visibility/versioned
|
||||
|
||||
install-schema-es:
|
||||
@printf $(COLOR) "Install Elasticsearch schema..."
|
||||
@@ -500,8 +482,7 @@ start-cass-es: temporal-server
|
||||
start-es-fi: temporal-server
|
||||
./temporal-server --env development-cass-es-fi --allow-no-auth start
|
||||
|
||||
start-mysql: temporal-server
|
||||
./temporal-server --env development-mysql --allow-no-auth start
|
||||
start-mysql: start-mysql8
|
||||
|
||||
start-mysql8: temporal-server
|
||||
./temporal-server --env development-mysql8 --allow-no-auth start
|
||||
@@ -509,8 +490,7 @@ start-mysql8: temporal-server
|
||||
start-mysql-es: temporal-server
|
||||
./temporal-server --env development-mysql-es --allow-no-auth start
|
||||
|
||||
start-postgres: temporal-server
|
||||
./temporal-server --env development-postgres --allow-no-auth start
|
||||
start-postgres: start-postgres12
|
||||
|
||||
start-postgres12: temporal-server
|
||||
./temporal-server --env development-postgres12 --allow-no-auth start
|
||||
|
||||
@@ -149,9 +149,9 @@ func NewTestBaseWithSQL(options *TestBaseOptions) *TestBase {
|
||||
|
||||
if options.DBPort == 0 {
|
||||
switch options.SQLDBPluginName {
|
||||
case mysql.PluginName, mysql.PluginNameV8:
|
||||
case mysql.PluginNameV8:
|
||||
options.DBPort = environment.GetMySQLPort()
|
||||
case postgresql.PluginName, postgresql.PluginNamePGX, postgresql.PluginNameV12, postgresql.PluginNameV12PGX:
|
||||
case postgresql.PluginNameV12, postgresql.PluginNameV12PGX:
|
||||
options.DBPort = environment.GetPostgreSQLPort()
|
||||
case sqlite.PluginName:
|
||||
options.DBPort = 0
|
||||
@@ -161,9 +161,9 @@ func NewTestBaseWithSQL(options *TestBaseOptions) *TestBase {
|
||||
}
|
||||
if options.DBHost == "" {
|
||||
switch options.SQLDBPluginName {
|
||||
case mysql.PluginName, mysql.PluginNameV8:
|
||||
case mysql.PluginNameV8:
|
||||
options.DBHost = environment.GetMySQLAddress()
|
||||
case postgresql.PluginName, postgresql.PluginNamePGX:
|
||||
case postgresql.PluginNameV12, postgresql.PluginNameV12PGX:
|
||||
options.DBHost = environment.GetPostgreSQLAddress()
|
||||
case sqlite.PluginName:
|
||||
options.DBHost = environment.GetLocalhostIP()
|
||||
|
||||
@@ -35,12 +35,10 @@ import (
|
||||
const (
|
||||
testMySQLUser = "temporal"
|
||||
testMySQLPassword = "temporal"
|
||||
testMySQLSchemaDir = "schema/mysql/v57"
|
||||
testMySQL8SchemaDir = "schema/mysql/v8"
|
||||
|
||||
testPostgreSQLUser = "temporal"
|
||||
testPostgreSQLPassword = "temporal"
|
||||
testPostgreSQLSchemaDir = "schema/postgresql/v96"
|
||||
testPostgreSQL12SchemaDir = "schema/postgresql/v12"
|
||||
|
||||
testSQLiteUser = ""
|
||||
@@ -50,19 +48,6 @@ const (
|
||||
testSQLiteSchemaDir = "schema/sqlite/v3" // specify if mode is not "memory"
|
||||
)
|
||||
|
||||
// GetMySQLTestClusterOption return test options
|
||||
func GetMySQLTestClusterOption() *TestBaseOptions {
|
||||
return &TestBaseOptions{
|
||||
SQLDBPluginName: mysql.PluginName,
|
||||
DBUsername: testMySQLUser,
|
||||
DBPassword: testMySQLPassword,
|
||||
DBHost: environment.GetMySQLAddress(),
|
||||
DBPort: environment.GetMySQLPort(),
|
||||
SchemaDir: testMySQLSchemaDir,
|
||||
StoreType: config.StoreTypeSQL,
|
||||
}
|
||||
}
|
||||
|
||||
// GetMySQL8TestClusterOption return test options
|
||||
func GetMySQL8TestClusterOption() *TestBaseOptions {
|
||||
return &TestBaseOptions{
|
||||
@@ -76,32 +61,6 @@ func GetMySQL8TestClusterOption() *TestBaseOptions {
|
||||
}
|
||||
}
|
||||
|
||||
// GetPostgreSQLTestClusterOption return test options
|
||||
func GetPostgreSQLTestClusterOption() *TestBaseOptions {
|
||||
return &TestBaseOptions{
|
||||
SQLDBPluginName: postgresql.PluginName,
|
||||
DBUsername: testPostgreSQLUser,
|
||||
DBPassword: testPostgreSQLPassword,
|
||||
DBHost: environment.GetPostgreSQLAddress(),
|
||||
DBPort: environment.GetPostgreSQLPort(),
|
||||
SchemaDir: testPostgreSQLSchemaDir,
|
||||
StoreType: config.StoreTypeSQL,
|
||||
}
|
||||
}
|
||||
|
||||
// GetPostgreSQLPGXTestClusterOption return test options
|
||||
func GetPostgreSQLPGXTestClusterOption() *TestBaseOptions {
|
||||
return &TestBaseOptions{
|
||||
SQLDBPluginName: postgresql.PluginNamePGX,
|
||||
DBUsername: testPostgreSQLUser,
|
||||
DBPassword: testPostgreSQLPassword,
|
||||
DBHost: environment.GetPostgreSQLAddress(),
|
||||
DBPort: environment.GetPostgreSQLPort(),
|
||||
SchemaDir: testPostgreSQLSchemaDir,
|
||||
StoreType: config.StoreTypeSQL,
|
||||
}
|
||||
}
|
||||
|
||||
// GetPostgreSQL12TestClusterOption return test options
|
||||
func GetPostgreSQL12TestClusterOption() *TestBaseOptions {
|
||||
return &TestBaseOptions{
|
||||
|
||||
@@ -58,7 +58,7 @@ const (
|
||||
`PRIMARY KEY (version_partition, year, month, update_time));`
|
||||
|
||||
// NOTE: we have to use %v because somehow mysql doesn't work with ? here
|
||||
createDatabaseQuery = "CREATE DATABASE IF NOT EXISTS %v CHARACTER SET UTF8"
|
||||
createDatabaseQuery = "CREATE DATABASE IF NOT EXISTS %v CHARACTER SET utf8mb4"
|
||||
|
||||
dropDatabaseQuery = "DROP DATABASE IF EXISTS %v"
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
// NOTE: we have to use %v because somehow mysql doesn't work with ? here
|
||||
createDatabaseQuery_v8 = "CREATE DATABASE IF NOT EXISTS %v CHARACTER SET utf8mb4"
|
||||
)
|
||||
|
||||
// CreateDatabase creates a database if it doesn't exist
|
||||
func (mdb *dbV8) CreateDatabase(name string) error {
|
||||
return mdb.Exec(fmt.Sprintf(createDatabaseQuery_v8, name))
|
||||
}
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
|
||||
"go.temporal.io/server/common/persistence/schema"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
mysqlschemaV57 "go.temporal.io/server/schema/mysql/v57"
|
||||
mysqlschemaV8 "go.temporal.io/server/schema/mysql/v8"
|
||||
)
|
||||
|
||||
// db represents a logical connection to mysql database
|
||||
@@ -108,7 +108,7 @@ func (mdb *db) Close() error {
|
||||
|
||||
// PluginName returns the name of the mysql plugin
|
||||
func (mdb *db) PluginName() string {
|
||||
return PluginName
|
||||
return PluginNameV8
|
||||
}
|
||||
|
||||
// DbName returns the name of the database
|
||||
@@ -120,9 +120,9 @@ func (mdb *db) DbName() string {
|
||||
func (mdb *db) ExpectedVersion() string {
|
||||
switch mdb.dbKind {
|
||||
case sqlplugin.DbKindMain:
|
||||
return mysqlschemaV57.Version
|
||||
return mysqlschemaV8.Version
|
||||
case sqlplugin.DbKindVisibility:
|
||||
return mysqlschemaV57.VisibilityVersion
|
||||
return mysqlschemaV8.VisibilityVersion
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown db kind %v", mdb.dbKind))
|
||||
}
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
|
||||
"go.temporal.io/server/common/persistence/schema"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
mysqlschemaV8 "go.temporal.io/server/schema/mysql/v8"
|
||||
)
|
||||
|
||||
// db represents a logical connection to mysql database
|
||||
type dbV8 struct {
|
||||
db
|
||||
}
|
||||
|
||||
var _ sqlplugin.AdminDB = (*dbV8)(nil)
|
||||
var _ sqlplugin.DB = (*dbV8)(nil)
|
||||
var _ sqlplugin.Tx = (*dbV8)(nil)
|
||||
|
||||
// newDB returns an instance of DB, which is a logical
|
||||
// connection to the underlying mysql database
|
||||
func newDBV8(
|
||||
dbKind sqlplugin.DbKind,
|
||||
dbName string,
|
||||
xdb *sqlx.DB,
|
||||
tx *sqlx.Tx,
|
||||
) *dbV8 {
|
||||
mdb := &dbV8{
|
||||
db: db{
|
||||
dbKind: dbKind,
|
||||
dbName: dbName,
|
||||
db: xdb,
|
||||
tx: tx,
|
||||
},
|
||||
}
|
||||
mdb.conn = xdb
|
||||
if tx != nil {
|
||||
mdb.conn = tx
|
||||
}
|
||||
mdb.converter = &converter{}
|
||||
return mdb
|
||||
}
|
||||
|
||||
// BeginTx starts a new transaction and returns a reference to the Tx object
|
||||
func (mdb *dbV8) BeginTx(ctx context.Context) (sqlplugin.Tx, error) {
|
||||
xtx, err := mdb.db.db.BeginTxx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newDBV8(mdb.dbKind, mdb.dbName, mdb.db.db, xtx), nil
|
||||
}
|
||||
|
||||
// PluginName returns the name of the mysql plugin
|
||||
func (mdb *dbV8) PluginName() string {
|
||||
return PluginNameV8
|
||||
}
|
||||
|
||||
// ExpectedVersion returns expected version.
|
||||
func (mdb *dbV8) ExpectedVersion() string {
|
||||
switch mdb.dbKind {
|
||||
case sqlplugin.DbKindMain:
|
||||
return mysqlschemaV8.Version
|
||||
case sqlplugin.DbKindVisibility:
|
||||
return mysqlschemaV8.VisibilityVersion
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown db kind %v", mdb.dbKind))
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyVersion verify schema version is up to date
|
||||
func (mdb *dbV8) VerifyVersion() error {
|
||||
expectedVersion := mdb.ExpectedVersion()
|
||||
return schema.VerifyCompatibleVersion(mdb, mdb.dbName, expectedVersion)
|
||||
}
|
||||
@@ -36,7 +36,7 @@ import (
|
||||
|
||||
const (
|
||||
// PluginName is the name of the plugin
|
||||
PluginName = "mysql"
|
||||
PluginNameV8 = "mysql8"
|
||||
)
|
||||
|
||||
type plugin struct{}
|
||||
@@ -44,7 +44,7 @@ type plugin struct{}
|
||||
var _ sqlplugin.Plugin = (*plugin)(nil)
|
||||
|
||||
func init() {
|
||||
sql.RegisterPlugin(PluginName, &plugin{})
|
||||
sql.RegisterPlugin(PluginNameV8, &plugin{})
|
||||
}
|
||||
|
||||
// CreateDB initialize the db object
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"go.temporal.io/server/common/config"
|
||||
"go.temporal.io/server/common/persistence/sql"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
"go.temporal.io/server/common/resolver"
|
||||
)
|
||||
|
||||
const (
|
||||
// PluginName is the name of the plugin
|
||||
PluginNameV8 = "mysql8"
|
||||
)
|
||||
|
||||
type pluginV8 struct {
|
||||
plugin
|
||||
}
|
||||
|
||||
var _ sqlplugin.Plugin = (*pluginV8)(nil)
|
||||
|
||||
func init() {
|
||||
sql.RegisterPlugin(PluginNameV8, &pluginV8{})
|
||||
}
|
||||
|
||||
// CreateDB initialize the db object
|
||||
func (p *pluginV8) CreateDB(
|
||||
dbKind sqlplugin.DbKind,
|
||||
cfg *config.SQL,
|
||||
r resolver.ServiceResolver,
|
||||
) (sqlplugin.DB, error) {
|
||||
conn, err := p.createDBConnection(cfg, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db := newDBV8(dbKind, cfg.DatabaseName, conn, nil)
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// CreateAdminDB initialize the db object
|
||||
func (p *pluginV8) CreateAdminDB(
|
||||
dbKind sqlplugin.DbKind,
|
||||
cfg *config.SQL,
|
||||
r resolver.ServiceResolver,
|
||||
) (sqlplugin.AdminDB, error) {
|
||||
conn, err := p.createDBConnection(cfg, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db := newDBV8(dbKind, cfg.DatabaseName, conn, nil)
|
||||
return db, nil
|
||||
}
|
||||
@@ -29,148 +29,161 @@ import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
"go.temporal.io/server/common/persistence/visibility/store"
|
||||
)
|
||||
|
||||
const (
|
||||
templateCreateWorkflowExecutionStarted = `INSERT INTO executions_visibility (` +
|
||||
`namespace_id, workflow_id, run_id, start_time, execution_time, workflow_type_name, status, memo, encoding, task_queue) ` +
|
||||
`VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ` +
|
||||
`ON DUPLICATE KEY UPDATE ` +
|
||||
`run_id=VALUES(run_id)`
|
||||
var (
|
||||
templateInsertWorkflowExecution = fmt.Sprintf(
|
||||
`INSERT INTO executions_visibility (%s)
|
||||
VALUES (%s)
|
||||
ON DUPLICATE KEY UPDATE run_id = VALUES(run_id)`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
sqlplugin.BuildNamedPlaceholder(sqlplugin.DbFields...),
|
||||
)
|
||||
|
||||
templateCreateWorkflowExecutionClosed = `INSERT INTO executions_visibility (` +
|
||||
`namespace_id, workflow_id, run_id, start_time, execution_time, workflow_type_name, close_time, status, history_length, memo, encoding, task_queue) ` +
|
||||
`VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ` +
|
||||
`ON DUPLICATE KEY UPDATE workflow_id = VALUES(workflow_id), start_time = VALUES(start_time), execution_time = VALUES(execution_time), workflow_type_name = VALUES(workflow_type_name), ` +
|
||||
`close_time = VALUES(close_time), status = VALUES(status), history_length = VALUES(history_length), memo = VALUES(memo), encoding = VALUES(encoding), task_queue = VALUES(task_queue)`
|
||||
templateInsertCustomSearchAttributes = `
|
||||
INSERT INTO custom_search_attributes (
|
||||
namespace_id, run_id, search_attributes
|
||||
) VALUES (:namespace_id, :run_id, :search_attributes)
|
||||
ON DUPLICATE KEY UPDATE run_id = VALUES(run_id)`
|
||||
|
||||
// RunID condition is needed for correct pagination
|
||||
templateConditions = ` AND namespace_id = ?
|
||||
AND start_time >= ?
|
||||
AND start_time <= ?
|
||||
AND ((run_id > ? and start_time = ?) OR (start_time < ?))
|
||||
ORDER BY start_time DESC, run_id
|
||||
LIMIT ?`
|
||||
templateUpsertWorkflowExecution = fmt.Sprintf(
|
||||
`INSERT INTO executions_visibility (%s)
|
||||
VALUES (%s)
|
||||
%s`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
sqlplugin.BuildNamedPlaceholder(sqlplugin.DbFields...),
|
||||
buildOnDuplicateKeyUpdate(sqlplugin.DbFields...),
|
||||
)
|
||||
|
||||
templateConditionsClosedWorkflows = ` AND namespace_id = ?
|
||||
AND close_time >= ?
|
||||
AND close_time <= ?
|
||||
AND ((run_id > ? and close_time = ?) OR (close_time < ?))
|
||||
ORDER BY close_time DESC, run_id
|
||||
LIMIT ?`
|
||||
templateUpsertCustomSearchAttributes = `
|
||||
INSERT INTO custom_search_attributes (
|
||||
namespace_id, run_id, search_attributes
|
||||
) VALUES (:namespace_id, :run_id, :search_attributes)
|
||||
ON DUPLICATE KEY UPDATE search_attributes = VALUES(search_attributes)`
|
||||
|
||||
templateOpenFieldNames = `workflow_id, run_id, start_time, execution_time, workflow_type_name, status, memo, encoding, task_queue`
|
||||
templateOpenSelect = `SELECT ` + templateOpenFieldNames + ` FROM executions_visibility WHERE status = 1 `
|
||||
templateDeleteWorkflowExecution_v8 = `
|
||||
DELETE FROM executions_visibility
|
||||
WHERE namespace_id = :namespace_id AND run_id = :run_id`
|
||||
|
||||
templateClosedSelect = `SELECT ` + templateOpenFieldNames + `, close_time, history_length
|
||||
FROM executions_visibility WHERE status != 1 `
|
||||
templateDeleteCustomSearchAttributes = `
|
||||
DELETE FROM custom_search_attributes
|
||||
WHERE namespace_id = :namespace_id AND run_id = :run_id`
|
||||
|
||||
templateGetOpenWorkflowExecutions = templateOpenSelect + templateConditions
|
||||
|
||||
templateGetClosedWorkflowExecutions = templateClosedSelect + templateConditionsClosedWorkflows
|
||||
|
||||
templateGetOpenWorkflowExecutionsByType = templateOpenSelect + `AND workflow_type_name = ?` + templateConditions
|
||||
|
||||
templateGetClosedWorkflowExecutionsByType = templateClosedSelect + `AND workflow_type_name = ?` + templateConditionsClosedWorkflows
|
||||
|
||||
templateGetOpenWorkflowExecutionsByID = templateOpenSelect + `AND workflow_id = ?` + templateConditions
|
||||
|
||||
templateGetClosedWorkflowExecutionsByID = templateClosedSelect + `AND workflow_id = ?` + templateConditionsClosedWorkflows
|
||||
|
||||
templateGetClosedWorkflowExecutionsByStatus = templateClosedSelect + `AND status = ?` + templateConditionsClosedWorkflows
|
||||
|
||||
templateGetClosedWorkflowExecution = `SELECT workflow_id, run_id, start_time, execution_time, memo, encoding, close_time, workflow_type_name, status, history_length, task_queue
|
||||
FROM executions_visibility
|
||||
WHERE namespace_id = ? AND status != 1
|
||||
AND run_id = ?`
|
||||
|
||||
templateGetWorkflowExecution = `
|
||||
SELECT
|
||||
workflow_id,
|
||||
run_id,
|
||||
start_time,
|
||||
execution_time,
|
||||
memo,
|
||||
encoding,
|
||||
close_time,
|
||||
workflow_type_name,
|
||||
status,
|
||||
history_length,
|
||||
task_queue
|
||||
FROM executions_visibility
|
||||
WHERE namespace_id = ? AND run_id = ?`
|
||||
|
||||
templateDeleteWorkflowExecution = "DELETE FROM executions_visibility WHERE namespace_id = ? AND run_id = ?"
|
||||
templateGetWorkflowExecution_v8 = fmt.Sprintf(
|
||||
`SELECT %s FROM executions_visibility
|
||||
WHERE namespace_id = :namespace_id AND run_id = :run_id`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
)
|
||||
)
|
||||
|
||||
var errCloseParams = errors.New("missing one of {CloseTime, HistoryLength} params")
|
||||
func buildOnDuplicateKeyUpdate(fields ...string) string {
|
||||
items := make([]string, len(fields))
|
||||
for i, field := range fields {
|
||||
items[i] = fmt.Sprintf("%s = VALUES(%s)", field, field)
|
||||
}
|
||||
return fmt.Sprintf("ON DUPLICATE KEY UPDATE %s", strings.Join(items, ", "))
|
||||
}
|
||||
|
||||
// InsertIntoVisibility inserts a row into visibility table. If an row already exist,
|
||||
// its left as such and no update will be made
|
||||
func (mdb *db) InsertIntoVisibility(
|
||||
ctx context.Context,
|
||||
row *sqlplugin.VisibilityRow,
|
||||
) (sql.Result, error) {
|
||||
row.StartTime = mdb.converter.ToMySQLDateTime(row.StartTime)
|
||||
row.ExecutionTime = mdb.converter.ToMySQLDateTime(row.ExecutionTime)
|
||||
return mdb.conn.ExecContext(ctx,
|
||||
templateCreateWorkflowExecutionStarted,
|
||||
row.NamespaceID,
|
||||
row.WorkflowID,
|
||||
row.RunID,
|
||||
row.StartTime,
|
||||
row.ExecutionTime,
|
||||
row.WorkflowTypeName,
|
||||
row.Status,
|
||||
row.Memo,
|
||||
row.Encoding,
|
||||
row.TaskQueue,
|
||||
)
|
||||
) (result sql.Result, retError error) {
|
||||
finalRow := mdb.prepareRowForDB(row)
|
||||
tx, err := mdb.db.BeginTxx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
err := tx.Rollback()
|
||||
// If the error is sql.ErrTxDone, it means the transaction already closed, so ignore error.
|
||||
if err != nil && !errors.Is(err, sql.ErrTxDone) {
|
||||
// Transaction rollback error should never happen, unless db connection was lost.
|
||||
retError = fmt.Errorf("transaction rollback failed: %w", retError)
|
||||
}
|
||||
}()
|
||||
result, err = tx.NamedExecContext(ctx, templateInsertWorkflowExecution, finalRow)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = tx.NamedExecContext(ctx, templateInsertCustomSearchAttributes, finalRow)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ReplaceIntoVisibility replaces an existing row if it exist or creates a new row in visibility table
|
||||
func (mdb *db) ReplaceIntoVisibility(
|
||||
ctx context.Context,
|
||||
row *sqlplugin.VisibilityRow,
|
||||
) (sql.Result, error) {
|
||||
switch {
|
||||
case row.CloseTime != nil && row.HistoryLength != nil:
|
||||
row.StartTime = mdb.converter.ToMySQLDateTime(row.StartTime)
|
||||
row.ExecutionTime = mdb.converter.ToMySQLDateTime(row.ExecutionTime)
|
||||
closeTime := mdb.converter.ToMySQLDateTime(*row.CloseTime)
|
||||
return mdb.conn.ExecContext(ctx,
|
||||
templateCreateWorkflowExecutionClosed,
|
||||
row.NamespaceID,
|
||||
row.WorkflowID,
|
||||
row.RunID,
|
||||
row.StartTime,
|
||||
row.ExecutionTime,
|
||||
row.WorkflowTypeName,
|
||||
closeTime,
|
||||
row.Status,
|
||||
*row.HistoryLength,
|
||||
row.Memo,
|
||||
row.Encoding,
|
||||
row.TaskQueue,
|
||||
)
|
||||
default:
|
||||
return nil, errCloseParams
|
||||
) (result sql.Result, retError error) {
|
||||
finalRow := mdb.prepareRowForDB(row)
|
||||
tx, err := mdb.db.BeginTxx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
err := tx.Rollback()
|
||||
// If the error is sql.ErrTxDone, it means the transaction already closed, so ignore error.
|
||||
if err != nil && !errors.Is(err, sql.ErrTxDone) {
|
||||
// Transaction rollback error should never happen, unless db connection was lost.
|
||||
retError = fmt.Errorf("transaction rollback failed: %w", retError)
|
||||
}
|
||||
}()
|
||||
result, err = tx.NamedExecContext(ctx, templateUpsertWorkflowExecution, finalRow)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = tx.NamedExecContext(ctx, templateUpsertCustomSearchAttributes, finalRow)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DeleteFromVisibility deletes a row from visibility table if it exist
|
||||
func (mdb *db) DeleteFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilityDeleteFilter,
|
||||
) (sql.Result, error) {
|
||||
return mdb.conn.ExecContext(ctx,
|
||||
templateDeleteWorkflowExecution,
|
||||
filter.NamespaceID,
|
||||
filter.RunID,
|
||||
)
|
||||
) (result sql.Result, retError error) {
|
||||
tx, err := mdb.db.BeginTxx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
err := tx.Rollback()
|
||||
// If the error is sql.ErrTxDone, it means the transaction already closed, so ignore error.
|
||||
if err != nil && !errors.Is(err, sql.ErrTxDone) {
|
||||
// Transaction rollback error should never happen, unless db connection was lost.
|
||||
retError = fmt.Errorf("transaction rollback failed: %w", retError)
|
||||
}
|
||||
}()
|
||||
_, err = mdb.conn.NamedExecContext(ctx, templateDeleteCustomSearchAttributes, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err = mdb.conn.NamedExecContext(ctx, templateDeleteWorkflowExecution_v8, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SelectFromVisibility reads one or more rows from visibility table
|
||||
@@ -178,103 +191,24 @@ func (mdb *db) SelectFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) ([]sqlplugin.VisibilityRow, error) {
|
||||
var err error
|
||||
if len(filter.Query) == 0 {
|
||||
// backward compatibility for existing tests
|
||||
err := sqlplugin.GenerateSelectQuery(&filter, mdb.converter.ToMySQLDateTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var rows []sqlplugin.VisibilityRow
|
||||
if filter.MinTime != nil {
|
||||
*filter.MinTime = mdb.converter.ToMySQLDateTime(*filter.MinTime)
|
||||
}
|
||||
if filter.MaxTime != nil {
|
||||
*filter.MaxTime = mdb.converter.ToMySQLDateTime(*filter.MaxTime)
|
||||
}
|
||||
// If filter.Status == 0 (UNSPECIFIED) then only closed workflows will be returned (all excluding 1 (RUNNING)).
|
||||
switch {
|
||||
case filter.MinTime == nil && filter.RunID != nil && filter.Status != 1:
|
||||
var row sqlplugin.VisibilityRow
|
||||
err = mdb.conn.GetContext(ctx,
|
||||
&row,
|
||||
templateGetClosedWorkflowExecution,
|
||||
filter.NamespaceID,
|
||||
*filter.RunID,
|
||||
)
|
||||
if err == nil {
|
||||
rows = append(rows, row)
|
||||
}
|
||||
case filter.MinTime != nil && filter.MaxTime != nil &&
|
||||
filter.WorkflowID != nil && filter.RunID != nil && filter.PageSize != nil:
|
||||
qry := templateGetOpenWorkflowExecutionsByID
|
||||
if filter.Status != 1 {
|
||||
qry = templateGetClosedWorkflowExecutionsByID
|
||||
}
|
||||
err = mdb.conn.SelectContext(ctx,
|
||||
&rows,
|
||||
qry,
|
||||
*filter.WorkflowID,
|
||||
filter.NamespaceID,
|
||||
*filter.MinTime,
|
||||
*filter.MaxTime,
|
||||
*filter.RunID,
|
||||
*filter.MaxTime,
|
||||
*filter.MaxTime,
|
||||
*filter.PageSize,
|
||||
)
|
||||
case filter.MinTime != nil && filter.MaxTime != nil &&
|
||||
filter.WorkflowTypeName != nil && filter.RunID != nil && filter.PageSize != nil:
|
||||
qry := templateGetOpenWorkflowExecutionsByType
|
||||
if filter.Status != 1 {
|
||||
qry = templateGetClosedWorkflowExecutionsByType
|
||||
}
|
||||
err = mdb.conn.SelectContext(ctx,
|
||||
&rows,
|
||||
qry,
|
||||
*filter.WorkflowTypeName,
|
||||
filter.NamespaceID,
|
||||
*filter.MinTime,
|
||||
*filter.MaxTime,
|
||||
*filter.RunID,
|
||||
*filter.MaxTime,
|
||||
*filter.MaxTime,
|
||||
*filter.PageSize,
|
||||
)
|
||||
case filter.MinTime != nil && filter.MaxTime != nil &&
|
||||
filter.RunID != nil && filter.PageSize != nil &&
|
||||
filter.Status != 0 && filter.Status != 1: // 0 is UNSPECIFIED, 1 is RUNNING
|
||||
err = mdb.conn.SelectContext(ctx,
|
||||
&rows,
|
||||
templateGetClosedWorkflowExecutionsByStatus,
|
||||
filter.Status,
|
||||
filter.NamespaceID,
|
||||
*filter.MinTime,
|
||||
*filter.MaxTime,
|
||||
*filter.RunID,
|
||||
*filter.MaxTime,
|
||||
*filter.MaxTime,
|
||||
*filter.PageSize,
|
||||
)
|
||||
case filter.MinTime != nil && filter.MaxTime != nil &&
|
||||
filter.RunID != nil && filter.PageSize != nil:
|
||||
qry := templateGetOpenWorkflowExecutions
|
||||
if filter.Status != 1 {
|
||||
qry = templateGetClosedWorkflowExecutions
|
||||
}
|
||||
err = mdb.conn.SelectContext(ctx,
|
||||
&rows,
|
||||
qry,
|
||||
filter.NamespaceID,
|
||||
*filter.MinTime,
|
||||
*filter.MaxTime,
|
||||
*filter.RunID,
|
||||
*filter.MaxTime,
|
||||
*filter.MaxTime,
|
||||
*filter.PageSize,
|
||||
)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid query filter")
|
||||
}
|
||||
err := mdb.conn.SelectContext(ctx, &rows, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range rows {
|
||||
mdb.processRowFromDB(&rows[i])
|
||||
err = mdb.processRowFromDB(&rows[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
@@ -285,16 +219,18 @@ func (mdb *db) GetFromVisibility(
|
||||
filter sqlplugin.VisibilityGetFilter,
|
||||
) (*sqlplugin.VisibilityRow, error) {
|
||||
var row sqlplugin.VisibilityRow
|
||||
err := mdb.conn.GetContext(ctx,
|
||||
&row,
|
||||
templateGetWorkflowExecution,
|
||||
filter.NamespaceID,
|
||||
filter.RunID,
|
||||
)
|
||||
stmt, err := mdb.conn.PrepareNamedContext(ctx, templateGetWorkflowExecution_v8)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = stmt.GetContext(ctx, &row, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = mdb.processRowFromDB(&row)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mdb.processRowFromDB(&row)
|
||||
return &row, nil
|
||||
}
|
||||
|
||||
@@ -302,21 +238,68 @@ func (mdb *db) CountFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) (int64, error) {
|
||||
return 0, store.OperationNotSupportedErr
|
||||
var count int64
|
||||
err := mdb.conn.GetContext(ctx, &count, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (mdb *db) CountGroupByFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) ([]sqlplugin.VisibilityCountRow, error) {
|
||||
return nil, store.OperationNotSupportedErr
|
||||
rows, err := mdb.db.QueryContext(ctx, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sqlplugin.ParseCountGroupByRows(rows, filter.GroupBy)
|
||||
}
|
||||
|
||||
func (mdb *db) processRowFromDB(row *sqlplugin.VisibilityRow) {
|
||||
func (mdb *db) prepareRowForDB(row *sqlplugin.VisibilityRow) *sqlplugin.VisibilityRow {
|
||||
if row == nil {
|
||||
return nil
|
||||
}
|
||||
finalRow := *row
|
||||
finalRow.StartTime = mdb.converter.ToMySQLDateTime(finalRow.StartTime)
|
||||
finalRow.ExecutionTime = mdb.converter.ToMySQLDateTime(finalRow.ExecutionTime)
|
||||
if finalRow.CloseTime != nil {
|
||||
*finalRow.CloseTime = mdb.converter.ToMySQLDateTime(*finalRow.CloseTime)
|
||||
}
|
||||
return &finalRow
|
||||
}
|
||||
|
||||
func (mdb *db) processRowFromDB(row *sqlplugin.VisibilityRow) error {
|
||||
if row == nil {
|
||||
return nil
|
||||
}
|
||||
row.StartTime = mdb.converter.FromMySQLDateTime(row.StartTime)
|
||||
row.ExecutionTime = mdb.converter.FromMySQLDateTime(row.ExecutionTime)
|
||||
if row.CloseTime != nil {
|
||||
closeTime := mdb.converter.FromMySQLDateTime(*row.CloseTime)
|
||||
row.CloseTime = &closeTime
|
||||
}
|
||||
if row.SearchAttributes != nil {
|
||||
for saName, saValue := range *row.SearchAttributes {
|
||||
switch typedSaValue := saValue.(type) {
|
||||
case []interface{}:
|
||||
// the only valid type is slice of strings
|
||||
strSlice := make([]string, len(typedSaValue))
|
||||
for i, item := range typedSaValue {
|
||||
switch v := item.(type) {
|
||||
case string:
|
||||
strSlice[i] = v
|
||||
default:
|
||||
return fmt.Errorf("%w: %T (expected string)", sqlplugin.ErrInvalidKeywordListDataType, v)
|
||||
}
|
||||
}
|
||||
(*row.SearchAttributes)[saName] = strSlice
|
||||
default:
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,305 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
)
|
||||
|
||||
var (
|
||||
templateInsertWorkflowExecution = fmt.Sprintf(
|
||||
`INSERT INTO executions_visibility (%s)
|
||||
VALUES (%s)
|
||||
ON DUPLICATE KEY UPDATE run_id = VALUES(run_id)`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
sqlplugin.BuildNamedPlaceholder(sqlplugin.DbFields...),
|
||||
)
|
||||
|
||||
templateInsertCustomSearchAttributes = `
|
||||
INSERT INTO custom_search_attributes (
|
||||
namespace_id, run_id, search_attributes
|
||||
) VALUES (:namespace_id, :run_id, :search_attributes)
|
||||
ON DUPLICATE KEY UPDATE run_id = VALUES(run_id)`
|
||||
|
||||
templateUpsertWorkflowExecution = fmt.Sprintf(
|
||||
`INSERT INTO executions_visibility (%s)
|
||||
VALUES (%s)
|
||||
%s`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
sqlplugin.BuildNamedPlaceholder(sqlplugin.DbFields...),
|
||||
buildOnDuplicateKeyUpdate(sqlplugin.DbFields...),
|
||||
)
|
||||
|
||||
templateUpsertCustomSearchAttributes = `
|
||||
INSERT INTO custom_search_attributes (
|
||||
namespace_id, run_id, search_attributes
|
||||
) VALUES (:namespace_id, :run_id, :search_attributes)
|
||||
ON DUPLICATE KEY UPDATE search_attributes = VALUES(search_attributes)`
|
||||
|
||||
templateDeleteWorkflowExecution_v8 = `
|
||||
DELETE FROM executions_visibility
|
||||
WHERE namespace_id = :namespace_id AND run_id = :run_id`
|
||||
|
||||
templateDeleteCustomSearchAttributes = `
|
||||
DELETE FROM custom_search_attributes
|
||||
WHERE namespace_id = :namespace_id AND run_id = :run_id`
|
||||
|
||||
templateGetWorkflowExecution_v8 = fmt.Sprintf(
|
||||
`SELECT %s FROM executions_visibility
|
||||
WHERE namespace_id = :namespace_id AND run_id = :run_id`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
)
|
||||
)
|
||||
|
||||
func buildOnDuplicateKeyUpdate(fields ...string) string {
|
||||
items := make([]string, len(fields))
|
||||
for i, field := range fields {
|
||||
items[i] = fmt.Sprintf("%s = VALUES(%s)", field, field)
|
||||
}
|
||||
return fmt.Sprintf("ON DUPLICATE KEY UPDATE %s", strings.Join(items, ", "))
|
||||
}
|
||||
|
||||
// InsertIntoVisibility inserts a row into visibility table. If an row already exist,
|
||||
// its left as such and no update will be made
|
||||
func (mdb *dbV8) InsertIntoVisibility(
|
||||
ctx context.Context,
|
||||
row *sqlplugin.VisibilityRow,
|
||||
) (result sql.Result, retError error) {
|
||||
finalRow := mdb.prepareRowForDB(row)
|
||||
tx, err := mdb.db.db.BeginTxx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
err := tx.Rollback()
|
||||
// If the error is sql.ErrTxDone, it means the transaction already closed, so ignore error.
|
||||
if err != nil && !errors.Is(err, sql.ErrTxDone) {
|
||||
// Transaction rollback error should never happen, unless db connection was lost.
|
||||
retError = fmt.Errorf("transaction rollback failed: %w", retError)
|
||||
}
|
||||
}()
|
||||
result, err = tx.NamedExecContext(ctx, templateInsertWorkflowExecution, finalRow)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = tx.NamedExecContext(ctx, templateInsertCustomSearchAttributes, finalRow)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ReplaceIntoVisibility replaces an existing row if it exist or creates a new row in visibility table
|
||||
func (mdb *dbV8) ReplaceIntoVisibility(
|
||||
ctx context.Context,
|
||||
row *sqlplugin.VisibilityRow,
|
||||
) (result sql.Result, retError error) {
|
||||
finalRow := mdb.prepareRowForDB(row)
|
||||
tx, err := mdb.db.db.BeginTxx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
err := tx.Rollback()
|
||||
// If the error is sql.ErrTxDone, it means the transaction already closed, so ignore error.
|
||||
if err != nil && !errors.Is(err, sql.ErrTxDone) {
|
||||
// Transaction rollback error should never happen, unless db connection was lost.
|
||||
retError = fmt.Errorf("transaction rollback failed: %w", retError)
|
||||
}
|
||||
}()
|
||||
result, err = tx.NamedExecContext(ctx, templateUpsertWorkflowExecution, finalRow)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = tx.NamedExecContext(ctx, templateUpsertCustomSearchAttributes, finalRow)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DeleteFromVisibility deletes a row from visibility table if it exist
|
||||
func (mdb *dbV8) DeleteFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilityDeleteFilter,
|
||||
) (result sql.Result, retError error) {
|
||||
tx, err := mdb.db.db.BeginTxx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
err := tx.Rollback()
|
||||
// If the error is sql.ErrTxDone, it means the transaction already closed, so ignore error.
|
||||
if err != nil && !errors.Is(err, sql.ErrTxDone) {
|
||||
// Transaction rollback error should never happen, unless db connection was lost.
|
||||
retError = fmt.Errorf("transaction rollback failed: %w", retError)
|
||||
}
|
||||
}()
|
||||
_, err = mdb.conn.NamedExecContext(ctx, templateDeleteCustomSearchAttributes, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err = mdb.conn.NamedExecContext(ctx, templateDeleteWorkflowExecution_v8, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SelectFromVisibility reads one or more rows from visibility table
|
||||
func (mdb *dbV8) SelectFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) ([]sqlplugin.VisibilityRow, error) {
|
||||
if len(filter.Query) == 0 {
|
||||
// backward compatibility for existing tests
|
||||
err := sqlplugin.GenerateSelectQuery(&filter, mdb.converter.ToMySQLDateTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var rows []sqlplugin.VisibilityRow
|
||||
err := mdb.conn.SelectContext(ctx, &rows, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range rows {
|
||||
err = mdb.processRowFromDB(&rows[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// GetFromVisibility reads one row from visibility table
|
||||
func (mdb *dbV8) GetFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilityGetFilter,
|
||||
) (*sqlplugin.VisibilityRow, error) {
|
||||
var row sqlplugin.VisibilityRow
|
||||
stmt, err := mdb.conn.PrepareNamedContext(ctx, templateGetWorkflowExecution_v8)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = stmt.GetContext(ctx, &row, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = mdb.processRowFromDB(&row)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &row, nil
|
||||
}
|
||||
|
||||
func (mdb *dbV8) CountFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) (int64, error) {
|
||||
var count int64
|
||||
err := mdb.conn.GetContext(ctx, &count, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (mdb *dbV8) CountGroupByFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) ([]sqlplugin.VisibilityCountRow, error) {
|
||||
rows, err := mdb.db.db.QueryContext(ctx, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sqlplugin.ParseCountGroupByRows(rows, filter.GroupBy)
|
||||
}
|
||||
|
||||
func (mdb *dbV8) prepareRowForDB(row *sqlplugin.VisibilityRow) *sqlplugin.VisibilityRow {
|
||||
if row == nil {
|
||||
return nil
|
||||
}
|
||||
finalRow := *row
|
||||
finalRow.StartTime = mdb.converter.ToMySQLDateTime(finalRow.StartTime)
|
||||
finalRow.ExecutionTime = mdb.converter.ToMySQLDateTime(finalRow.ExecutionTime)
|
||||
if finalRow.CloseTime != nil {
|
||||
*finalRow.CloseTime = mdb.converter.ToMySQLDateTime(*finalRow.CloseTime)
|
||||
}
|
||||
return &finalRow
|
||||
}
|
||||
|
||||
func (mdb *dbV8) processRowFromDB(row *sqlplugin.VisibilityRow) error {
|
||||
if row == nil {
|
||||
return nil
|
||||
}
|
||||
row.StartTime = mdb.converter.FromMySQLDateTime(row.StartTime)
|
||||
row.ExecutionTime = mdb.converter.FromMySQLDateTime(row.ExecutionTime)
|
||||
if row.CloseTime != nil {
|
||||
closeTime := mdb.converter.FromMySQLDateTime(*row.CloseTime)
|
||||
row.CloseTime = &closeTime
|
||||
}
|
||||
if row.SearchAttributes != nil {
|
||||
for saName, saValue := range *row.SearchAttributes {
|
||||
switch typedSaValue := saValue.(type) {
|
||||
case []interface{}:
|
||||
// the only valid type is slice of strings
|
||||
strSlice := make([]string, len(typedSaValue))
|
||||
for i, item := range typedSaValue {
|
||||
switch v := item.(type) {
|
||||
case string:
|
||||
strSlice[i] = v
|
||||
default:
|
||||
return fmt.Errorf("Unexpected data type in keyword list: %T (expected string)", v)
|
||||
}
|
||||
}
|
||||
(*row.SearchAttributes)[saName] = strSlice
|
||||
default:
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -32,7 +32,7 @@ import (
|
||||
"go.temporal.io/server/common/persistence/schema"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin/postgresql/driver"
|
||||
postgresqlschemaV96 "go.temporal.io/server/schema/postgresql/v96"
|
||||
postgresqlschemaV12 "go.temporal.io/server/schema/postgresql/v12"
|
||||
)
|
||||
|
||||
func (pdb *db) IsDupEntryError(err error) bool {
|
||||
@@ -108,7 +108,7 @@ func (pdb *db) Close() error {
|
||||
|
||||
// PluginName returns the name of the mysql plugin
|
||||
func (pdb *db) PluginName() string {
|
||||
return PluginName
|
||||
return PluginNameV12
|
||||
}
|
||||
|
||||
// DbName returns the name of the database
|
||||
@@ -120,9 +120,9 @@ func (pdb *db) DbName() string {
|
||||
func (pdb *db) ExpectedVersion() string {
|
||||
switch pdb.dbKind {
|
||||
case sqlplugin.DbKindMain:
|
||||
return postgresqlschemaV96.Version
|
||||
return postgresqlschemaV12.Version
|
||||
case sqlplugin.DbKindVisibility:
|
||||
return postgresqlschemaV96.VisibilityVersion
|
||||
return postgresqlschemaV12.VisibilityVersion
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown db kind %v", pdb.dbKind))
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
|
||||
"go.temporal.io/server/common/persistence/schema"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin/postgresql/driver"
|
||||
postgresqlschemaV12 "go.temporal.io/server/schema/postgresql/v12"
|
||||
)
|
||||
|
||||
// dbV12 represents a logical connection to mysql database
|
||||
type dbV12 struct {
|
||||
db
|
||||
}
|
||||
|
||||
var _ sqlplugin.DB = (*dbV12)(nil)
|
||||
var _ sqlplugin.Tx = (*dbV12)(nil)
|
||||
|
||||
// newDB returns an instance of DB, which is a logical
|
||||
// connection to the underlying postgresql database
|
||||
func newDBV12(
|
||||
dbKind sqlplugin.DbKind,
|
||||
dbName string,
|
||||
dbDriver driver.Driver,
|
||||
xdb *sqlx.DB,
|
||||
tx *sqlx.Tx,
|
||||
) *dbV12 {
|
||||
mdb := &dbV12{
|
||||
db: db{
|
||||
dbKind: dbKind,
|
||||
dbName: dbName,
|
||||
dbDriver: dbDriver,
|
||||
db: xdb,
|
||||
tx: tx,
|
||||
},
|
||||
}
|
||||
mdb.conn = xdb
|
||||
if tx != nil {
|
||||
mdb.conn = tx
|
||||
}
|
||||
mdb.converter = &converter{}
|
||||
return mdb
|
||||
}
|
||||
|
||||
// BeginTx starts a new transaction and returns a reference to the Tx object
|
||||
func (pdb *dbV12) BeginTx(ctx context.Context) (sqlplugin.Tx, error) {
|
||||
xtx, err := pdb.db.db.BeginTxx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newDB(pdb.dbKind, pdb.dbName, pdb.dbDriver, pdb.db.db, xtx), nil
|
||||
}
|
||||
|
||||
// PluginName returns the name of the mysql plugin
|
||||
func (pdb *dbV12) PluginName() string {
|
||||
return PluginNameV12
|
||||
}
|
||||
|
||||
// ExpectedVersion returns expected version.
|
||||
func (pdb *dbV12) ExpectedVersion() string {
|
||||
switch pdb.dbKind {
|
||||
case sqlplugin.DbKindMain:
|
||||
return postgresqlschemaV12.Version
|
||||
case sqlplugin.DbKindVisibility:
|
||||
return postgresqlschemaV12.VisibilityVersion
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown db kind %v", pdb.dbKind))
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyVersion verify schema version is up to date
|
||||
func (pdb *dbV12) VerifyVersion() error {
|
||||
expectedVersion := pdb.ExpectedVersion()
|
||||
return schema.VerifyCompatibleVersion(pdb, pdb.dbName, expectedVersion)
|
||||
}
|
||||
@@ -41,8 +41,8 @@ import (
|
||||
|
||||
const (
|
||||
// PluginName is the name of the plugin
|
||||
PluginName = "postgres"
|
||||
PluginNamePGX = "postgres_pgx"
|
||||
PluginNameV12 = "postgres12"
|
||||
PluginNameV12PGX = "postgres12_pgx"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -59,8 +59,8 @@ type plugin struct {
|
||||
var _ sqlplugin.Plugin = (*plugin)(nil)
|
||||
|
||||
func init() {
|
||||
sql.RegisterPlugin(PluginName, &plugin{&driver.PQDriver{}})
|
||||
sql.RegisterPlugin(PluginNamePGX, &plugin{&driver.PGXDriver{}})
|
||||
sql.RegisterPlugin(PluginNameV12, &plugin{&driver.PQDriver{}})
|
||||
sql.RegisterPlugin(PluginNameV12PGX, &plugin{&driver.PGXDriver{}})
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"go.temporal.io/server/common/config"
|
||||
"go.temporal.io/server/common/persistence/sql"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin/postgresql/driver"
|
||||
"go.temporal.io/server/common/resolver"
|
||||
)
|
||||
|
||||
const (
|
||||
// PluginName is the name of the plugin
|
||||
PluginNameV12 = "postgres12"
|
||||
PluginNameV12PGX = "postgres12_pgx"
|
||||
)
|
||||
|
||||
type pluginV12 struct {
|
||||
plugin
|
||||
}
|
||||
|
||||
var _ sqlplugin.Plugin = (*pluginV12)(nil)
|
||||
|
||||
func init() {
|
||||
sql.RegisterPlugin(PluginNameV12, &pluginV12{plugin{&driver.PQDriver{}}})
|
||||
sql.RegisterPlugin(PluginNameV12PGX, &pluginV12{plugin{&driver.PGXDriver{}}})
|
||||
|
||||
}
|
||||
|
||||
// CreateDB initialize the db object
|
||||
func (d *pluginV12) CreateDB(
|
||||
dbKind sqlplugin.DbKind,
|
||||
cfg *config.SQL,
|
||||
r resolver.ServiceResolver,
|
||||
) (sqlplugin.DB, error) {
|
||||
conn, err := d.createDBConnection(cfg, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db := newDBV12(dbKind, cfg.DatabaseName, d.d, conn, nil)
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// CreateAdminDB initialize the adminDB object
|
||||
func (d *pluginV12) CreateAdminDB(
|
||||
dbKind sqlplugin.DbKind,
|
||||
cfg *config.SQL,
|
||||
r resolver.ServiceResolver,
|
||||
) (sqlplugin.AdminDB, error) {
|
||||
conn, err := d.createDBConnection(cfg, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db := newDBV12(dbKind, cfg.DatabaseName, d.d, conn, nil)
|
||||
return db, nil
|
||||
}
|
||||
@@ -27,109 +27,51 @@ package postgresql
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
"go.temporal.io/server/common/persistence/visibility/store"
|
||||
)
|
||||
|
||||
const (
|
||||
templateCreateWorkflowExecutionStarted = `INSERT INTO executions_visibility (` +
|
||||
`namespace_id, workflow_id, run_id, start_time, execution_time, workflow_type_name, status, memo, encoding, task_queue) ` +
|
||||
`VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||
ON CONFLICT (namespace_id, run_id) DO NOTHING`
|
||||
var (
|
||||
templateInsertWorkflowExecution = fmt.Sprintf(
|
||||
`INSERT INTO executions_visibility (%s)
|
||||
VALUES (%s)
|
||||
ON CONFLICT (namespace_id, run_id) DO NOTHING`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
sqlplugin.BuildNamedPlaceholder(sqlplugin.DbFields...),
|
||||
)
|
||||
|
||||
templateCreateWorkflowExecutionClosed = `INSERT INTO executions_visibility (` +
|
||||
`namespace_id, workflow_id, run_id, start_time, execution_time, workflow_type_name, close_time, status, history_length, memo, encoding, task_queue) ` +
|
||||
`VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||||
ON CONFLICT (namespace_id, run_id) DO UPDATE
|
||||
SET workflow_id = excluded.workflow_id,
|
||||
start_time = excluded.start_time,
|
||||
execution_time = excluded.execution_time,
|
||||
workflow_type_name = excluded.workflow_type_name,
|
||||
close_time = excluded.close_time,
|
||||
status = excluded.status,
|
||||
history_length = excluded.history_length,
|
||||
memo = excluded.memo,
|
||||
encoding = excluded.encoding,
|
||||
task_queue = excluded.task_queue`
|
||||
templateUpsertWorkflowExecution = fmt.Sprintf(
|
||||
`INSERT INTO executions_visibility (%s)
|
||||
VALUES (%s)
|
||||
%s`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
sqlplugin.BuildNamedPlaceholder(sqlplugin.DbFields...),
|
||||
buildOnDuplicateKeyUpdate(sqlplugin.DbFields...),
|
||||
)
|
||||
|
||||
// RunID condition is needed for correct pagination
|
||||
templateConditions1 = ` AND namespace_id = $1
|
||||
AND start_time >= $2
|
||||
AND start_time <= $3
|
||||
AND ((run_id > $4 and start_time = $5) OR (start_time < $6))
|
||||
ORDER BY start_time DESC, run_id
|
||||
LIMIT $7`
|
||||
templateDeleteWorkflowExecution_v12 = `
|
||||
DELETE FROM executions_visibility
|
||||
WHERE namespace_id = :namespace_id AND run_id = :run_id`
|
||||
|
||||
templateConditions2 = ` AND namespace_id = $2
|
||||
AND start_time >= $3
|
||||
AND start_time <= $4
|
||||
AND ((run_id > $5 and start_time = $6) OR (start_time < $7))
|
||||
ORDER BY start_time DESC, run_id
|
||||
LIMIT $8`
|
||||
|
||||
templateConditionsClosedWorkflow1 = ` AND namespace_id = $1
|
||||
AND close_time >= $2
|
||||
AND close_time <= $3
|
||||
AND ((run_id > $4 and close_time = $5) OR (close_time < $6))
|
||||
ORDER BY close_time DESC, run_id
|
||||
LIMIT $7`
|
||||
|
||||
templateConditionsClosedWorkflow2 = ` AND namespace_id = $2
|
||||
AND close_time >= $3
|
||||
AND close_time <= $4
|
||||
AND ((run_id > $5 and close_time = $6) OR (close_time < $7))
|
||||
ORDER BY close_time DESC, run_id
|
||||
LIMIT $8`
|
||||
|
||||
templateOpenFieldNames = `workflow_id, run_id, start_time, execution_time, workflow_type_name, status, memo, encoding, task_queue`
|
||||
templateOpenSelect = `SELECT ` + templateOpenFieldNames + ` FROM executions_visibility WHERE status = 1 `
|
||||
|
||||
templateClosedSelect = `SELECT ` + templateOpenFieldNames + `, close_time, history_length
|
||||
FROM executions_visibility WHERE status != 1 `
|
||||
|
||||
templateGetOpenWorkflowExecutions = templateOpenSelect + templateConditions1
|
||||
|
||||
templateGetClosedWorkflowExecutions = templateClosedSelect + templateConditionsClosedWorkflow1
|
||||
|
||||
templateGetOpenWorkflowExecutionsByType = templateOpenSelect + `AND workflow_type_name = $1` + templateConditions2
|
||||
|
||||
templateGetClosedWorkflowExecutionsByType = templateClosedSelect + `AND workflow_type_name = $1` + templateConditionsClosedWorkflow2
|
||||
|
||||
templateGetOpenWorkflowExecutionsByID = templateOpenSelect + `AND workflow_id = $1` + templateConditions2
|
||||
|
||||
templateGetClosedWorkflowExecutionsByID = templateClosedSelect + `AND workflow_id = $1` + templateConditionsClosedWorkflow2
|
||||
|
||||
templateGetClosedWorkflowExecutionsByStatus = templateClosedSelect + `AND status = $1` + templateConditionsClosedWorkflow2
|
||||
|
||||
templateGetClosedWorkflowExecution = `SELECT workflow_id, run_id, start_time, execution_time, memo, encoding, close_time, workflow_type_name, status, history_length, task_queue
|
||||
FROM executions_visibility
|
||||
WHERE namespace_id = $1 AND status != 1
|
||||
AND run_id = $2`
|
||||
|
||||
templateGetWorkflowExecution = `
|
||||
SELECT
|
||||
workflow_id,
|
||||
run_id,
|
||||
start_time,
|
||||
execution_time,
|
||||
memo,
|
||||
encoding,
|
||||
close_time,
|
||||
workflow_type_name,
|
||||
status,
|
||||
history_length,
|
||||
task_queue
|
||||
FROM executions_visibility
|
||||
WHERE namespace_id = $1 AND run_id = $2`
|
||||
|
||||
templateDeleteWorkflowExecution = "DELETE FROM executions_visibility WHERE namespace_id = $1 AND run_id = $2"
|
||||
templateGetWorkflowExecution_v12 = fmt.Sprintf(
|
||||
`SELECT %s FROM executions_visibility
|
||||
WHERE namespace_id = :namespace_id AND run_id = :run_id`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
)
|
||||
)
|
||||
|
||||
var errCloseParams = errors.New("missing one of {closeTime, historyLength} params")
|
||||
func buildOnDuplicateKeyUpdate(fields ...string) string {
|
||||
items := make([]string, len(fields))
|
||||
for i, field := range fields {
|
||||
items[i] = fmt.Sprintf("%s = excluded.%s", field, field)
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
"ON CONFLICT (namespace_id, run_id) DO UPDATE SET %s",
|
||||
strings.Join(items, ", "),
|
||||
)
|
||||
}
|
||||
|
||||
// InsertIntoVisibility inserts a row into visibility table. If an row already exist,
|
||||
// its left as such and no update will be made
|
||||
@@ -137,21 +79,8 @@ func (pdb *db) InsertIntoVisibility(
|
||||
ctx context.Context,
|
||||
row *sqlplugin.VisibilityRow,
|
||||
) (sql.Result, error) {
|
||||
row.StartTime = pdb.converter.ToPostgreSQLDateTime(row.StartTime)
|
||||
row.ExecutionTime = pdb.converter.ToPostgreSQLDateTime(row.ExecutionTime)
|
||||
return pdb.conn.ExecContext(ctx,
|
||||
templateCreateWorkflowExecutionStarted,
|
||||
row.NamespaceID,
|
||||
row.WorkflowID,
|
||||
row.RunID,
|
||||
row.StartTime,
|
||||
row.ExecutionTime,
|
||||
row.WorkflowTypeName,
|
||||
row.Status,
|
||||
row.Memo,
|
||||
row.Encoding,
|
||||
row.TaskQueue,
|
||||
)
|
||||
finalRow := pdb.prepareRowForDB(row)
|
||||
return pdb.conn.NamedExecContext(ctx, templateInsertWorkflowExecution, finalRow)
|
||||
}
|
||||
|
||||
// ReplaceIntoVisibility replaces an existing row if it exist or creates a new row in visibility table
|
||||
@@ -159,29 +88,8 @@ func (pdb *db) ReplaceIntoVisibility(
|
||||
ctx context.Context,
|
||||
row *sqlplugin.VisibilityRow,
|
||||
) (sql.Result, error) {
|
||||
switch {
|
||||
case row.CloseTime != nil && row.HistoryLength != nil:
|
||||
row.StartTime = pdb.converter.ToPostgreSQLDateTime(row.StartTime)
|
||||
row.ExecutionTime = pdb.converter.ToPostgreSQLDateTime(row.ExecutionTime)
|
||||
closeTime := pdb.converter.ToPostgreSQLDateTime(*row.CloseTime)
|
||||
return pdb.conn.ExecContext(ctx,
|
||||
templateCreateWorkflowExecutionClosed,
|
||||
row.NamespaceID,
|
||||
row.WorkflowID,
|
||||
row.RunID,
|
||||
row.StartTime,
|
||||
row.ExecutionTime,
|
||||
row.WorkflowTypeName,
|
||||
closeTime,
|
||||
row.Status,
|
||||
*row.HistoryLength,
|
||||
row.Memo,
|
||||
row.Encoding,
|
||||
row.TaskQueue,
|
||||
)
|
||||
default:
|
||||
return nil, errCloseParams
|
||||
}
|
||||
finalRow := pdb.prepareRowForDB(row)
|
||||
return pdb.conn.NamedExecContext(ctx, templateUpsertWorkflowExecution, finalRow)
|
||||
}
|
||||
|
||||
// DeleteFromVisibility deletes a row from visibility table if it exist
|
||||
@@ -189,11 +97,7 @@ func (pdb *db) DeleteFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilityDeleteFilter,
|
||||
) (sql.Result, error) {
|
||||
return pdb.conn.ExecContext(ctx,
|
||||
templateDeleteWorkflowExecution,
|
||||
filter.NamespaceID,
|
||||
filter.RunID,
|
||||
)
|
||||
return pdb.conn.NamedExecContext(ctx, templateDeleteWorkflowExecution_v12, filter)
|
||||
}
|
||||
|
||||
// SelectFromVisibility reads one or more rows from visibility table
|
||||
@@ -201,99 +105,26 @@ func (pdb *db) SelectFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) ([]sqlplugin.VisibilityRow, error) {
|
||||
var err error
|
||||
if len(filter.Query) == 0 {
|
||||
// backward compatibility for existing tests
|
||||
err := sqlplugin.GenerateSelectQuery(&filter, pdb.converter.ToPostgreSQLDateTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Rebind will replace default placeholder `?` with the right placeholder for PostgreSQL.
|
||||
filter.Query = pdb.db.Rebind(filter.Query)
|
||||
var rows []sqlplugin.VisibilityRow
|
||||
if filter.MinTime != nil {
|
||||
*filter.MinTime = pdb.converter.ToPostgreSQLDateTime(*filter.MinTime)
|
||||
}
|
||||
if filter.MaxTime != nil {
|
||||
*filter.MaxTime = pdb.converter.ToPostgreSQLDateTime(*filter.MaxTime)
|
||||
}
|
||||
// If filter.Status == 0 (UNSPECIFIED) then only closed workflows will be returned (all excluding 1 (RUNNING)).
|
||||
switch {
|
||||
case filter.MinTime == nil && filter.RunID != nil && filter.Status != 1:
|
||||
var row sqlplugin.VisibilityRow
|
||||
err = pdb.conn.GetContext(ctx,
|
||||
&row,
|
||||
templateGetClosedWorkflowExecution,
|
||||
filter.NamespaceID,
|
||||
*filter.RunID,
|
||||
)
|
||||
if err == nil {
|
||||
rows = append(rows, row)
|
||||
}
|
||||
case filter.MinTime != nil && filter.MaxTime != nil &&
|
||||
filter.WorkflowID != nil && filter.RunID != nil && filter.PageSize != nil:
|
||||
qry := templateGetOpenWorkflowExecutionsByID
|
||||
if filter.Status != 1 {
|
||||
qry = templateGetClosedWorkflowExecutionsByID
|
||||
}
|
||||
err = pdb.conn.SelectContext(ctx,
|
||||
&rows,
|
||||
qry,
|
||||
*filter.WorkflowID,
|
||||
filter.NamespaceID,
|
||||
*filter.MinTime,
|
||||
*filter.MaxTime,
|
||||
*filter.RunID,
|
||||
*filter.MaxTime,
|
||||
*filter.MaxTime,
|
||||
*filter.PageSize)
|
||||
case filter.MinTime != nil && filter.MaxTime != nil &&
|
||||
filter.WorkflowTypeName != nil && filter.RunID != nil && filter.PageSize != nil:
|
||||
qry := templateGetOpenWorkflowExecutionsByType
|
||||
if filter.Status != 1 {
|
||||
qry = templateGetClosedWorkflowExecutionsByType
|
||||
}
|
||||
err = pdb.conn.SelectContext(ctx,
|
||||
&rows,
|
||||
qry,
|
||||
*filter.WorkflowTypeName,
|
||||
filter.NamespaceID,
|
||||
*filter.MinTime,
|
||||
*filter.MaxTime,
|
||||
*filter.RunID,
|
||||
*filter.MaxTime,
|
||||
*filter.MaxTime,
|
||||
*filter.PageSize)
|
||||
case filter.MinTime != nil && filter.MaxTime != nil &&
|
||||
filter.RunID != nil && filter.PageSize != nil &&
|
||||
filter.Status != 0 && filter.Status != 1: // 0 is UNSPECIFIED, 1 is RUNNING
|
||||
err = pdb.conn.SelectContext(ctx,
|
||||
&rows,
|
||||
templateGetClosedWorkflowExecutionsByStatus,
|
||||
filter.Status,
|
||||
filter.NamespaceID,
|
||||
*filter.MinTime,
|
||||
*filter.MaxTime,
|
||||
*filter.RunID,
|
||||
*filter.MaxTime,
|
||||
*filter.MaxTime,
|
||||
*filter.PageSize)
|
||||
case filter.MinTime != nil && filter.MaxTime != nil &&
|
||||
filter.RunID != nil && filter.PageSize != nil:
|
||||
qry := templateGetOpenWorkflowExecutions
|
||||
if filter.Status != 1 {
|
||||
qry = templateGetClosedWorkflowExecutions
|
||||
}
|
||||
err = pdb.conn.SelectContext(ctx,
|
||||
&rows,
|
||||
qry,
|
||||
filter.NamespaceID,
|
||||
*filter.MinTime,
|
||||
*filter.MaxTime,
|
||||
*filter.RunID,
|
||||
*filter.MaxTime,
|
||||
*filter.MaxTime,
|
||||
*filter.PageSize)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid query filter")
|
||||
}
|
||||
err := pdb.conn.SelectContext(ctx, &rows, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range rows {
|
||||
pdb.processRowFromDB(&rows[i])
|
||||
err = pdb.processRowFromDB(&rows[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
@@ -304,16 +135,18 @@ func (pdb *db) GetFromVisibility(
|
||||
filter sqlplugin.VisibilityGetFilter,
|
||||
) (*sqlplugin.VisibilityRow, error) {
|
||||
var row sqlplugin.VisibilityRow
|
||||
err := pdb.conn.GetContext(ctx,
|
||||
&row,
|
||||
templateGetWorkflowExecution,
|
||||
filter.NamespaceID,
|
||||
filter.RunID,
|
||||
)
|
||||
stmt, err := pdb.conn.PrepareNamedContext(ctx, templateGetWorkflowExecution_v12)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = stmt.GetContext(ctx, &row, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = pdb.processRowFromDB(&row)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pdb.processRowFromDB(&row)
|
||||
return &row, nil
|
||||
}
|
||||
|
||||
@@ -321,24 +154,73 @@ func (pdb *db) CountFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) (int64, error) {
|
||||
return 0, store.OperationNotSupportedErr
|
||||
var count int64
|
||||
filter.Query = pdb.db.Rebind(filter.Query)
|
||||
err := pdb.conn.GetContext(ctx, &count, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (pdb *db) CountGroupByFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) ([]sqlplugin.VisibilityCountRow, error) {
|
||||
return nil, store.OperationNotSupportedErr
|
||||
filter.Query = pdb.db.Rebind(filter.Query)
|
||||
rows, err := pdb.db.QueryContext(ctx, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sqlplugin.ParseCountGroupByRows(rows, filter.GroupBy)
|
||||
}
|
||||
|
||||
func (pdb *db) processRowFromDB(row *sqlplugin.VisibilityRow) {
|
||||
func (pdb *db) prepareRowForDB(row *sqlplugin.VisibilityRow) *sqlplugin.VisibilityRow {
|
||||
if row == nil {
|
||||
return nil
|
||||
}
|
||||
finalRow := *row
|
||||
finalRow.StartTime = pdb.converter.ToPostgreSQLDateTime(finalRow.StartTime)
|
||||
finalRow.ExecutionTime = pdb.converter.ToPostgreSQLDateTime(finalRow.ExecutionTime)
|
||||
if finalRow.CloseTime != nil {
|
||||
*finalRow.CloseTime = pdb.converter.ToPostgreSQLDateTime(*finalRow.CloseTime)
|
||||
}
|
||||
return &finalRow
|
||||
}
|
||||
|
||||
func (pdb *db) processRowFromDB(row *sqlplugin.VisibilityRow) error {
|
||||
if row == nil {
|
||||
return nil
|
||||
}
|
||||
row.StartTime = pdb.converter.FromPostgreSQLDateTime(row.StartTime)
|
||||
row.ExecutionTime = pdb.converter.FromPostgreSQLDateTime(row.ExecutionTime)
|
||||
if row.CloseTime != nil {
|
||||
closeTime := pdb.converter.FromPostgreSQLDateTime(*row.CloseTime)
|
||||
row.CloseTime = &closeTime
|
||||
}
|
||||
if row.SearchAttributes != nil {
|
||||
for saName, saValue := range *row.SearchAttributes {
|
||||
switch typedSaValue := saValue.(type) {
|
||||
case []interface{}:
|
||||
// the only valid type is slice of strings
|
||||
strSlice := make([]string, len(typedSaValue))
|
||||
for i, item := range typedSaValue {
|
||||
switch v := item.(type) {
|
||||
case string:
|
||||
strSlice[i] = v
|
||||
default:
|
||||
return fmt.Errorf("%w: %T (expected string)", sqlplugin.ErrInvalidKeywordListDataType, v)
|
||||
}
|
||||
}
|
||||
(*row.SearchAttributes)[saName] = strSlice
|
||||
default:
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
// need to trim the run ID, or otherwise the returned value will
|
||||
// come with lots of trailing spaces, probably due to the CHAR(64) type
|
||||
// come with lots of trailing spaces, probably due to the CHAR(64) type
|
||||
row.RunID = strings.TrimSpace(row.RunID)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
)
|
||||
|
||||
var (
|
||||
templateInsertWorkflowExecution = fmt.Sprintf(
|
||||
`INSERT INTO executions_visibility (%s)
|
||||
VALUES (%s)
|
||||
ON CONFLICT (namespace_id, run_id) DO NOTHING`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
sqlplugin.BuildNamedPlaceholder(sqlplugin.DbFields...),
|
||||
)
|
||||
|
||||
templateUpsertWorkflowExecution = fmt.Sprintf(
|
||||
`INSERT INTO executions_visibility (%s)
|
||||
VALUES (%s)
|
||||
%s`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
sqlplugin.BuildNamedPlaceholder(sqlplugin.DbFields...),
|
||||
buildOnDuplicateKeyUpdate(sqlplugin.DbFields...),
|
||||
)
|
||||
|
||||
templateDeleteWorkflowExecution_v12 = `
|
||||
DELETE FROM executions_visibility
|
||||
WHERE namespace_id = :namespace_id AND run_id = :run_id`
|
||||
|
||||
templateGetWorkflowExecution_v12 = fmt.Sprintf(
|
||||
`SELECT %s FROM executions_visibility
|
||||
WHERE namespace_id = :namespace_id AND run_id = :run_id`,
|
||||
strings.Join(sqlplugin.DbFields, ", "),
|
||||
)
|
||||
)
|
||||
|
||||
func buildOnDuplicateKeyUpdate(fields ...string) string {
|
||||
items := make([]string, len(fields))
|
||||
for i, field := range fields {
|
||||
items[i] = fmt.Sprintf("%s = excluded.%s", field, field)
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
"ON CONFLICT (namespace_id, run_id) DO UPDATE SET %s",
|
||||
strings.Join(items, ", "),
|
||||
)
|
||||
}
|
||||
|
||||
// InsertIntoVisibility inserts a row into visibility table. If an row already exist,
|
||||
// its left as such and no update will be made
|
||||
func (pdb *dbV12) InsertIntoVisibility(
|
||||
ctx context.Context,
|
||||
row *sqlplugin.VisibilityRow,
|
||||
) (sql.Result, error) {
|
||||
finalRow := pdb.prepareRowForDB(row)
|
||||
return pdb.conn.NamedExecContext(ctx, templateInsertWorkflowExecution, finalRow)
|
||||
}
|
||||
|
||||
// ReplaceIntoVisibility replaces an existing row if it exist or creates a new row in visibility table
|
||||
func (pdb *dbV12) ReplaceIntoVisibility(
|
||||
ctx context.Context,
|
||||
row *sqlplugin.VisibilityRow,
|
||||
) (sql.Result, error) {
|
||||
finalRow := pdb.prepareRowForDB(row)
|
||||
return pdb.conn.NamedExecContext(ctx, templateUpsertWorkflowExecution, finalRow)
|
||||
}
|
||||
|
||||
// DeleteFromVisibility deletes a row from visibility table if it exist
|
||||
func (pdb *dbV12) DeleteFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilityDeleteFilter,
|
||||
) (sql.Result, error) {
|
||||
return pdb.conn.NamedExecContext(ctx, templateDeleteWorkflowExecution_v12, filter)
|
||||
}
|
||||
|
||||
// SelectFromVisibility reads one or more rows from visibility table
|
||||
func (pdb *dbV12) SelectFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) ([]sqlplugin.VisibilityRow, error) {
|
||||
if len(filter.Query) == 0 {
|
||||
// backward compatibility for existing tests
|
||||
err := sqlplugin.GenerateSelectQuery(&filter, pdb.converter.ToPostgreSQLDateTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Rebind will replace default placeholder `?` with the right placeholder for PostgreSQL.
|
||||
filter.Query = pdb.db.db.Rebind(filter.Query)
|
||||
var rows []sqlplugin.VisibilityRow
|
||||
err := pdb.conn.SelectContext(ctx, &rows, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range rows {
|
||||
err = pdb.processRowFromDB(&rows[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// GetFromVisibility reads one row from visibility table
|
||||
func (pdb *dbV12) GetFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilityGetFilter,
|
||||
) (*sqlplugin.VisibilityRow, error) {
|
||||
var row sqlplugin.VisibilityRow
|
||||
stmt, err := pdb.conn.PrepareNamedContext(ctx, templateGetWorkflowExecution_v12)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = stmt.GetContext(ctx, &row, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = pdb.processRowFromDB(&row)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &row, nil
|
||||
}
|
||||
|
||||
func (pdb *dbV12) CountFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) (int64, error) {
|
||||
var count int64
|
||||
filter.Query = pdb.db.db.Rebind(filter.Query)
|
||||
err := pdb.conn.GetContext(ctx, &count, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (pdb *dbV12) CountGroupByFromVisibility(
|
||||
ctx context.Context,
|
||||
filter sqlplugin.VisibilitySelectFilter,
|
||||
) ([]sqlplugin.VisibilityCountRow, error) {
|
||||
filter.Query = pdb.db.db.Rebind(filter.Query)
|
||||
rows, err := pdb.db.db.QueryContext(ctx, filter.Query, filter.QueryArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sqlplugin.ParseCountGroupByRows(rows, filter.GroupBy)
|
||||
}
|
||||
|
||||
func (pdb *dbV12) prepareRowForDB(row *sqlplugin.VisibilityRow) *sqlplugin.VisibilityRow {
|
||||
if row == nil {
|
||||
return nil
|
||||
}
|
||||
finalRow := *row
|
||||
finalRow.StartTime = pdb.converter.ToPostgreSQLDateTime(finalRow.StartTime)
|
||||
finalRow.ExecutionTime = pdb.converter.ToPostgreSQLDateTime(finalRow.ExecutionTime)
|
||||
if finalRow.CloseTime != nil {
|
||||
*finalRow.CloseTime = pdb.converter.ToPostgreSQLDateTime(*finalRow.CloseTime)
|
||||
}
|
||||
return &finalRow
|
||||
}
|
||||
|
||||
func (pdb *dbV12) processRowFromDB(row *sqlplugin.VisibilityRow) error {
|
||||
if row == nil {
|
||||
return nil
|
||||
}
|
||||
row.StartTime = pdb.converter.FromPostgreSQLDateTime(row.StartTime)
|
||||
row.ExecutionTime = pdb.converter.FromPostgreSQLDateTime(row.ExecutionTime)
|
||||
if row.CloseTime != nil {
|
||||
closeTime := pdb.converter.FromPostgreSQLDateTime(*row.CloseTime)
|
||||
row.CloseTime = &closeTime
|
||||
}
|
||||
if row.SearchAttributes != nil {
|
||||
for saName, saValue := range *row.SearchAttributes {
|
||||
switch typedSaValue := saValue.(type) {
|
||||
case []interface{}:
|
||||
// the only valid type is slice of strings
|
||||
strSlice := make([]string, len(typedSaValue))
|
||||
for i, item := range typedSaValue {
|
||||
switch v := item.(type) {
|
||||
case string:
|
||||
strSlice[i] = v
|
||||
default:
|
||||
return fmt.Errorf("Unexpected data type in keyword list: %T (expected string)", v)
|
||||
}
|
||||
}
|
||||
(*row.SearchAttributes)[saName] = strSlice
|
||||
default:
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
// need to trim the run ID, or otherwise the returned value will
|
||||
// come with lots of trailing spaces, probably due to the CHAR(64) type
|
||||
row.RunID = strings.TrimSpace(row.RunID)
|
||||
return nil
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -41,6 +42,10 @@ import (
|
||||
"go.temporal.io/server/common/searchattribute"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidKeywordListDataType = errors.New("Unexpected data type in keyword list")
|
||||
)
|
||||
|
||||
type (
|
||||
// VisibilitySearchAttributes represents the search attributes json
|
||||
// in executions_visibility table
|
||||
|
||||
@@ -145,13 +145,6 @@ func TestMySQLTaskQueueTaskSuite(t *testing.T) {
|
||||
suite.Run(t, s)
|
||||
}
|
||||
|
||||
func TestMySQLVisibilityPersistenceSuite(t *testing.T) {
|
||||
s := &VisibilityPersistenceSuite{
|
||||
TestBase: persistencetests.NewTestBaseWithSQL(persistencetests.GetMySQLTestClusterOption()),
|
||||
}
|
||||
suite.Run(t, s)
|
||||
}
|
||||
|
||||
func TestMySQL8VisibilityPersistenceSuite(t *testing.T) {
|
||||
s := &VisibilityPersistenceSuite{
|
||||
TestBase: persistencetests.NewTestBaseWithSQL(persistencetests.GetMySQL8TestClusterOption()),
|
||||
@@ -161,34 +154,6 @@ func TestMySQL8VisibilityPersistenceSuite(t *testing.T) {
|
||||
|
||||
// TODO: Merge persistence-tests into the tests directory.
|
||||
|
||||
func TestMySQLHistoryV2PersistenceSuite(t *testing.T) {
|
||||
s := new(persistencetests.HistoryV2PersistenceSuite)
|
||||
s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetMySQLTestClusterOption())
|
||||
s.TestBase.Setup(nil)
|
||||
suite.Run(t, s)
|
||||
}
|
||||
|
||||
func TestMySQLMetadataPersistenceSuiteV2(t *testing.T) {
|
||||
s := new(persistencetests.MetadataPersistenceSuiteV2)
|
||||
s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetMySQLTestClusterOption())
|
||||
s.TestBase.Setup(nil)
|
||||
suite.Run(t, s)
|
||||
}
|
||||
|
||||
func TestMySQLQueuePersistence(t *testing.T) {
|
||||
s := new(persistencetests.QueuePersistenceSuite)
|
||||
s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetMySQLTestClusterOption())
|
||||
s.TestBase.Setup(nil)
|
||||
suite.Run(t, s)
|
||||
}
|
||||
|
||||
func TestMySQLClusterMetadataPersistence(t *testing.T) {
|
||||
s := new(persistencetests.ClusterMetadataManagerSuite)
|
||||
s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetMySQLTestClusterOption())
|
||||
s.TestBase.Setup(nil)
|
||||
suite.Run(t, s)
|
||||
}
|
||||
|
||||
func TestMySQL8HistoryV2PersistenceSuite(t *testing.T) {
|
||||
s := new(persistencetests.HistoryV2PersistenceSuite)
|
||||
s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetMySQL8TestClusterOption())
|
||||
|
||||
@@ -146,13 +146,6 @@ func (p *PostgreSQLSuite) TestPostgreSQLTaskQueueTaskSuite() {
|
||||
suite.Run(p.T(), s)
|
||||
}
|
||||
|
||||
func (p *PostgreSQLSuite) TestPostgreSQLVisibilityPersistenceSuite() {
|
||||
s := &VisibilityPersistenceSuite{
|
||||
TestBase: persistencetests.NewTestBaseWithSQL(persistencetests.GetPostgreSQLTestClusterOption()),
|
||||
}
|
||||
suite.Run(p.T(), s)
|
||||
}
|
||||
|
||||
func (p *PostgreSQLSuite) TestPostgreSQL12VisibilityPersistenceSuite() {
|
||||
s := &VisibilityPersistenceSuite{
|
||||
TestBase: persistencetests.NewTestBaseWithSQL(persistencetests.GetPostgreSQL12TestClusterOption()),
|
||||
@@ -162,45 +155,6 @@ func (p *PostgreSQLSuite) TestPostgreSQL12VisibilityPersistenceSuite() {
|
||||
|
||||
// TODO: Merge persistence-tests into the tests directory.
|
||||
|
||||
func (p *PostgreSQLSuite) TestPostgreSQLHistoryV2PersistenceSuite() {
|
||||
s := new(persistencetests.HistoryV2PersistenceSuite)
|
||||
s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetPostgreSQLTestClusterOption())
|
||||
s.TestBase.Setup(nil)
|
||||
suite.Run(p.T(), s)
|
||||
}
|
||||
|
||||
func (p *PostgreSQLSuite) TestPostgreSQLMetadataPersistenceSuiteV2() {
|
||||
s := new(persistencetests.MetadataPersistenceSuiteV2)
|
||||
s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetPostgreSQLTestClusterOption())
|
||||
s.TestBase.Setup(nil)
|
||||
suite.Run(p.T(), s)
|
||||
}
|
||||
|
||||
func (p *PostgreSQLSuite) TestPostgreSQLClusterMetadataPersistence() {
|
||||
s := new(persistencetests.ClusterMetadataManagerSuite)
|
||||
s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetPostgreSQLTestClusterOption())
|
||||
s.TestBase.Setup(nil)
|
||||
suite.Run(p.T(), s)
|
||||
}
|
||||
|
||||
// TODO flaky test in buildkite
|
||||
// https://go.temporal.io/server/issues/2877
|
||||
/*
|
||||
FAIL: TestPostgreSQLQueuePersistence/TestNamespaceReplicationQueue (0.26s)
|
||||
queuePersistenceTest.go:102:
|
||||
Error Trace: queuePersistenceTest.go:102
|
||||
Error: Not equal:
|
||||
expected: 99
|
||||
actual : 98
|
||||
Test: TestPostgreSQLQueuePersistence/TestNamespaceReplicationQueue
|
||||
*/
|
||||
// func (p *PostgreSQLSuite) TestPostgreSQLQueuePersistence() {
|
||||
// s := new(persistencetests.QueuePersistenceSuite)
|
||||
// s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetPostgreSQLTestClusterOption())
|
||||
// s.TestBase.Setup(nil)
|
||||
// suite.Run(p.T(), s)
|
||||
// }
|
||||
|
||||
func (p *PostgreSQLSuite) TestPostgreSQL12HistoryV2PersistenceSuite() {
|
||||
s := new(persistencetests.HistoryV2PersistenceSuite)
|
||||
s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetPostgreSQL12TestClusterOption())
|
||||
@@ -222,6 +176,24 @@ func (p *PostgreSQLSuite) TestPostgreSQL12ClusterMetadataPersistence() {
|
||||
suite.Run(p.T(), s)
|
||||
}
|
||||
|
||||
// TODO flaky test in buildkite
|
||||
// https://go.temporal.io/server/issues/2877
|
||||
/*
|
||||
FAIL: TestPostgreSQLQueuePersistence/TestNamespaceReplicationQueue (0.26s)
|
||||
queuePersistenceTest.go:102:
|
||||
Error Trace: queuePersistenceTest.go:102
|
||||
Error: Not equal:
|
||||
expected: 99
|
||||
actual : 98
|
||||
Test: TestPostgreSQLQueuePersistence/TestNamespaceReplicationQueue
|
||||
*/
|
||||
// func (p *PostgreSQLSuite) TestPostgreSQL12QueuePersistence() {
|
||||
// s := new(persistencetests.QueuePersistenceSuite)
|
||||
// s.TestBase = persistencetests.NewTestBaseWithSQL(persistencetests.GetPostgreSQL12TestClusterOption())
|
||||
// s.TestBase.Setup(nil)
|
||||
// suite.Run(p.T(), s)
|
||||
// }
|
||||
|
||||
// SQL store tests
|
||||
|
||||
func (p *PostgreSQLSuite) TestPostgreSQLNamespaceSuite() {
|
||||
|
||||
@@ -45,8 +45,6 @@ import (
|
||||
"go.temporal.io/server/common/payload"
|
||||
"go.temporal.io/server/common/persistence"
|
||||
persistencetests "go.temporal.io/server/common/persistence/persistence-tests"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin/mysql"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin/postgresql"
|
||||
"go.temporal.io/server/common/persistence/visibility"
|
||||
"go.temporal.io/server/common/persistence/visibility/manager"
|
||||
"go.temporal.io/server/common/primitives/timestamp"
|
||||
@@ -780,11 +778,6 @@ func (s *VisibilityPersistenceSuite) TestAdvancedVisibilityPagination() {
|
||||
}
|
||||
|
||||
func (s *VisibilityPersistenceSuite) TestCountWorkflowExecutions() {
|
||||
switch s.VisibilityMgr.GetStoreNames()[0] {
|
||||
case mysql.PluginName, postgresql.PluginName, postgresql.PluginNamePGX:
|
||||
s.T().Skip("Not supported by standard visibility")
|
||||
}
|
||||
|
||||
testNamespaceUUID := namespace.ID(uuid.New())
|
||||
closeTime := time.Now().UTC()
|
||||
startTime := closeTime.Add(-5 * time.Second)
|
||||
@@ -812,11 +805,6 @@ func (s *VisibilityPersistenceSuite) TestCountWorkflowExecutions() {
|
||||
}
|
||||
|
||||
func (s *VisibilityPersistenceSuite) TestCountGroupByWorkflowExecutions() {
|
||||
switch s.VisibilityMgr.GetStoreNames()[0] {
|
||||
case mysql.PluginName, postgresql.PluginName, postgresql.PluginNamePGX:
|
||||
s.T().Skip("Not supported by standard visibility")
|
||||
}
|
||||
|
||||
testNamespaceUUID := namespace.ID(uuid.New())
|
||||
closeTime := time.Now().UTC()
|
||||
startTime := closeTime.Add(-5 * time.Second)
|
||||
|
||||
@@ -86,9 +86,6 @@ func AllowListForValidation(
|
||||
case mysql.PluginNameV8, postgresql.PluginNameV12, postgresql.PluginNameV12PGX, sqlite.PluginName:
|
||||
// Advanced visibility with SQL DB don't support list of values
|
||||
return dynamicconfig.GetBoolPropertyFnFilteredByNamespace(false)
|
||||
case mysql.PluginName, postgresql.PluginName, postgresql.PluginNamePGX:
|
||||
// Standard visibility with SQL DB don't support list of values, but pass validation
|
||||
return dynamicconfig.GetBoolPropertyFnFilteredByNamespace(true)
|
||||
default:
|
||||
// Otherwise (ES), check dynamic config
|
||||
return allowList
|
||||
|
||||
@@ -38,8 +38,6 @@ import (
|
||||
"go.temporal.io/server/common/persistence/visibility/store/elasticsearch"
|
||||
esclient "go.temporal.io/server/common/persistence/visibility/store/elasticsearch/client"
|
||||
"go.temporal.io/server/common/persistence/visibility/store/sql"
|
||||
"go.temporal.io/server/common/persistence/visibility/store/standard"
|
||||
standardSql "go.temporal.io/server/common/persistence/visibility/store/standard/sql"
|
||||
"go.temporal.io/server/common/resolver"
|
||||
"go.temporal.io/server/common/searchattribute"
|
||||
)
|
||||
@@ -256,25 +254,13 @@ func newVisibilityStoreFromDataStoreConfig(
|
||||
err error
|
||||
)
|
||||
if dsConfig.SQL != nil {
|
||||
switch dsConfig.SQL.PluginName {
|
||||
case mysql.PluginNameV8, postgresql.PluginNameV12, postgresql.PluginNameV12PGX, sqlite.PluginName:
|
||||
visStore, err = sql.NewSQLVisibilityStore(
|
||||
*dsConfig.SQL,
|
||||
persistenceResolver,
|
||||
searchAttributesProvider,
|
||||
searchAttributesMapperProvider,
|
||||
logger,
|
||||
)
|
||||
default:
|
||||
visStore, err = newStandardVisibilityStore(
|
||||
dsConfig,
|
||||
persistenceResolver,
|
||||
searchAttributesProvider,
|
||||
searchAttributesMapperProvider,
|
||||
logger,
|
||||
metricsHandler,
|
||||
)
|
||||
}
|
||||
visStore, err = sql.NewSQLVisibilityStore(
|
||||
*dsConfig.SQL,
|
||||
persistenceResolver,
|
||||
searchAttributesProvider,
|
||||
searchAttributesMapperProvider,
|
||||
logger,
|
||||
)
|
||||
} else if dsConfig.Elasticsearch != nil {
|
||||
visStore = newElasticsearchVisibilityStore(
|
||||
dsConfig.Elasticsearch.GetVisibilityIndex(),
|
||||
@@ -298,39 +284,6 @@ func newVisibilityStoreFromDataStoreConfig(
|
||||
return visStore, err
|
||||
}
|
||||
|
||||
func newStandardVisibilityStore(
|
||||
dsConfig config.DataStore,
|
||||
persistenceResolver resolver.ServiceResolver,
|
||||
searchAttributesProvider searchattribute.Provider,
|
||||
searchAttributesMapperProvider searchattribute.MapperProvider,
|
||||
logger log.Logger,
|
||||
metricsHandler metrics.Handler,
|
||||
) (store.VisibilityStore, error) {
|
||||
var (
|
||||
visStore store.VisibilityStore
|
||||
err error
|
||||
)
|
||||
if dsConfig.SQL != nil {
|
||||
visStore, err = standardSql.NewSQLVisibilityStore(
|
||||
*dsConfig.SQL,
|
||||
persistenceResolver,
|
||||
logger,
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if visStore == nil {
|
||||
logger.Fatal("invalid config: sql params must be specified for visibility store")
|
||||
return nil, nil
|
||||
}
|
||||
return standard.NewVisibilityStore(
|
||||
visStore,
|
||||
searchAttributesProvider,
|
||||
searchAttributesMapperProvider,
|
||||
), nil
|
||||
}
|
||||
|
||||
func newElasticsearchVisibilityStore(
|
||||
defaultIndexName string,
|
||||
esClient esclient.Client,
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2021 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package standard
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/temporalio/sqlparser"
|
||||
enumspb "go.temporal.io/api/enums/v1"
|
||||
|
||||
"go.temporal.io/server/common/namespace"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
"go.temporal.io/server/common/persistence/visibility/store/query"
|
||||
"go.temporal.io/server/common/searchattribute"
|
||||
)
|
||||
|
||||
var allowedComparisonOperators = map[string]struct{}{
|
||||
sqlparser.EqualStr: {},
|
||||
}
|
||||
|
||||
type (
|
||||
converter struct {
|
||||
*query.Converter
|
||||
fvInterceptor *valuesInterceptor
|
||||
}
|
||||
)
|
||||
|
||||
func newQueryConverter(
|
||||
namespaceName namespace.Name,
|
||||
searchAttributesTypeMap searchattribute.NameTypeMap,
|
||||
searchAttributesMapperProvider searchattribute.MapperProvider,
|
||||
) *converter {
|
||||
fnInterceptor := newNameInterceptor()
|
||||
fvInterceptor := newValuesInterceptor(
|
||||
namespaceName,
|
||||
searchAttributesTypeMap,
|
||||
searchAttributesMapperProvider,
|
||||
)
|
||||
|
||||
rangeCond := query.NewRangeCondConverter(fnInterceptor, fvInterceptor, false)
|
||||
comparisonExpr := query.NewComparisonExprConverter(fnInterceptor, fvInterceptor, allowedComparisonOperators)
|
||||
|
||||
whereConverter := &query.WhereConverter{
|
||||
Or: query.NewNotSupportedExprConverter(),
|
||||
RangeCond: rangeCond,
|
||||
ComparisonExpr: comparisonExpr,
|
||||
Is: query.NewNotSupportedExprConverter(),
|
||||
}
|
||||
whereConverter.And = query.NewAndConverter(whereConverter)
|
||||
|
||||
return &converter{
|
||||
Converter: query.NewConverter(fnInterceptor, whereConverter),
|
||||
fvInterceptor: fvInterceptor,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *converter) GetFilter(whereOrderBy string) (*sqlplugin.VisibilitySelectFilter, error) {
|
||||
_, err := c.ConvertWhereOrderBy(whereOrderBy)
|
||||
if err != nil {
|
||||
// Convert ConverterError to InvalidArgument and pass through all other errors.
|
||||
var converterErr *query.ConverterError
|
||||
if errors.As(err, &converterErr) {
|
||||
return nil, converterErr.ToInvalidArgument()
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filter := c.fvInterceptor.filter
|
||||
numPredicates := 0
|
||||
|
||||
if filter.WorkflowID != nil {
|
||||
numPredicates++
|
||||
}
|
||||
|
||||
if filter.WorkflowTypeName != nil {
|
||||
numPredicates++
|
||||
}
|
||||
|
||||
if filter.Status != int32(enumspb.WORKFLOW_EXECUTION_STATUS_UNSPECIFIED) {
|
||||
numPredicates++
|
||||
}
|
||||
|
||||
if numPredicates > 1 {
|
||||
return nil, query.NewConverterError("too many filter conditions specified")
|
||||
}
|
||||
|
||||
if filter.MinTime == nil {
|
||||
minTime := time.Unix(0, 0)
|
||||
filter.MinTime = &minTime
|
||||
}
|
||||
|
||||
if filter.MaxTime == nil {
|
||||
maxTime := time.Now().Add(24 * time.Hour)
|
||||
filter.MaxTime = &maxTime
|
||||
}
|
||||
|
||||
return filter, nil
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2021 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package standard
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
enumspb "go.temporal.io/api/enums/v1"
|
||||
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
"go.temporal.io/server/common/searchattribute"
|
||||
"go.temporal.io/server/common/util"
|
||||
)
|
||||
|
||||
var startTimeFrom = time.Now().Add(-time.Hour)
|
||||
var startTimeTo = time.Now()
|
||||
var startTimeRangeFilter = fmt.Sprintf(`StartTime BETWEEN "%v" AND "%v"`, startTimeFrom.Format(time.RFC3339Nano), startTimeTo.Format(time.RFC3339Nano))
|
||||
|
||||
var supportedQuery = map[string]*sqlplugin.VisibilitySelectFilter{
|
||||
"": {},
|
||||
startTimeRangeFilter: {MinTime: &startTimeFrom, MaxTime: &startTimeTo},
|
||||
`WorkflowId = "abc"`: {WorkflowID: util.Ptr("abc")},
|
||||
`WorkflowId = "abc" AND ` + startTimeRangeFilter: {WorkflowID: util.Ptr("abc"), MinTime: &startTimeFrom, MaxTime: &startTimeTo},
|
||||
startTimeRangeFilter + ` AND WorkflowId = "abc"`: {WorkflowID: util.Ptr("abc"), MinTime: &startTimeFrom, MaxTime: &startTimeTo},
|
||||
`WorkflowType = "abc"`: {WorkflowTypeName: util.Ptr("abc")},
|
||||
`WorkflowType = "abc" AND ` + startTimeRangeFilter: {WorkflowTypeName: util.Ptr("abc"), MinTime: &startTimeFrom, MaxTime: &startTimeTo},
|
||||
startTimeRangeFilter + ` AND WorkflowType = "abc"`: {WorkflowTypeName: util.Ptr("abc"), MinTime: &startTimeFrom, MaxTime: &startTimeTo},
|
||||
`ExecutionStatus = "Running"`: {Status: int32(enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING)},
|
||||
`ExecutionStatus = "Running" AND ` + startTimeRangeFilter: {Status: int32(enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING), MinTime: &startTimeFrom, MaxTime: &startTimeTo},
|
||||
startTimeRangeFilter + ` AND ExecutionStatus = "Running"`: {Status: int32(enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING), MinTime: &startTimeFrom, MaxTime: &startTimeTo},
|
||||
}
|
||||
|
||||
// This is not an exhaustive list.
|
||||
var unsupportedQuery = []string{
|
||||
fmt.Sprintf(`StartTime NOT BETWEEN "%v" AND "%v"`, startTimeFrom.Format(time.RFC3339Nano), startTimeTo.Format(time.RFC3339Nano)),
|
||||
"order by WorkflowID",
|
||||
`WorkflowID = "abc" AND WorkflowType = "xyz"`,
|
||||
`ExecutionStatus = "Running" AND WorkflowType = "xyz"`,
|
||||
`WorkflowID = "abc" OR WorkflowType = "xyz"`,
|
||||
`WorkflowID != "abc"`,
|
||||
`StartTime < "2022-01-15T05:43:12.74127Z"`,
|
||||
}
|
||||
|
||||
func TestSupportedQueryFilters(t *testing.T) {
|
||||
for query, expectedFilter := range supportedQuery {
|
||||
converter := newQueryConverter("test-namespace", searchattribute.TestNameTypeMap, nil)
|
||||
filter, err := converter.GetFilter(query)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.EqualValues(t, expectedFilter.WorkflowID, filter.WorkflowID)
|
||||
assert.EqualValues(t, expectedFilter.WorkflowTypeName, filter.WorkflowTypeName)
|
||||
assert.EqualValues(t, expectedFilter.Status, filter.Status)
|
||||
|
||||
if expectedFilter.MinTime == nil {
|
||||
assert.True(t, time.Unix(0, 0).Equal(*filter.MinTime))
|
||||
} else {
|
||||
assert.NotNil(t, filter.MinTime)
|
||||
assert.True(t, expectedFilter.MinTime.Equal(*filter.MinTime))
|
||||
}
|
||||
|
||||
if expectedFilter.MaxTime == nil {
|
||||
assert.True(t, filter.MaxTime.After(time.Now()))
|
||||
} else {
|
||||
assert.NotNil(t, filter.MaxTime)
|
||||
assert.True(t, expectedFilter.MaxTime.Equal(*filter.MaxTime))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnsupportedQueryFilters(t *testing.T) {
|
||||
for _, query := range unsupportedQuery {
|
||||
converter := newQueryConverter("test-namespace", searchattribute.TestNameTypeMap, nil)
|
||||
_, err := converter.GetFilter(query)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2021 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package standard
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
enumspb "go.temporal.io/api/enums/v1"
|
||||
|
||||
"go.temporal.io/server/common/namespace"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
"go.temporal.io/server/common/persistence/visibility/store/elasticsearch"
|
||||
"go.temporal.io/server/common/persistence/visibility/store/query"
|
||||
"go.temporal.io/server/common/searchattribute"
|
||||
"go.temporal.io/server/common/util"
|
||||
)
|
||||
|
||||
var allowedFilters = []string{
|
||||
searchattribute.WorkflowID,
|
||||
searchattribute.WorkflowType,
|
||||
searchattribute.ExecutionStatus,
|
||||
searchattribute.StartTime,
|
||||
}
|
||||
|
||||
type (
|
||||
nameInterceptor struct{}
|
||||
valuesInterceptor struct {
|
||||
filter *sqlplugin.VisibilitySelectFilter
|
||||
nextInterceptor query.FieldValuesInterceptor
|
||||
}
|
||||
)
|
||||
|
||||
func newNameInterceptor() *nameInterceptor {
|
||||
return &nameInterceptor{}
|
||||
}
|
||||
|
||||
func newValuesInterceptor(
|
||||
namespaceName namespace.Name,
|
||||
searchAttributesTypeMap searchattribute.NameTypeMap,
|
||||
searchAttributesMapperProvider searchattribute.MapperProvider,
|
||||
) *valuesInterceptor {
|
||||
return &valuesInterceptor{
|
||||
filter: &sqlplugin.VisibilitySelectFilter{},
|
||||
nextInterceptor: elasticsearch.NewValuesInterceptor(
|
||||
namespaceName,
|
||||
searchAttributesTypeMap,
|
||||
searchAttributesMapperProvider,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (ni *nameInterceptor) Name(name string, usage query.FieldNameUsage) (string, error) {
|
||||
if usage == query.FieldNameSorter {
|
||||
return "", query.NewConverterError("order by not allowed for standard visibility")
|
||||
}
|
||||
|
||||
for _, filter := range allowedFilters {
|
||||
if filter == name {
|
||||
return name, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", query.NewConverterError("filter by '%v' not supported for standard visibility", name)
|
||||
}
|
||||
|
||||
func (vi *valuesInterceptor) Values(name string, values ...interface{}) ([]interface{}, error) {
|
||||
switch name {
|
||||
case searchattribute.WorkflowID:
|
||||
values, err := vi.nextInterceptor.Values(name, values...)
|
||||
if err == nil {
|
||||
vi.filter.WorkflowID = util.Ptr(values[0].(string))
|
||||
}
|
||||
return values, err
|
||||
case searchattribute.WorkflowType:
|
||||
values, err := vi.nextInterceptor.Values(name, values...)
|
||||
if err == nil {
|
||||
vi.filter.WorkflowTypeName = util.Ptr(values[0].(string))
|
||||
}
|
||||
return values, err
|
||||
case searchattribute.ExecutionStatus:
|
||||
values, err := vi.nextInterceptor.Values(name, values...)
|
||||
if err == nil {
|
||||
statusStr := values[0].(string)
|
||||
e, err := enumspb.WorkflowExecutionStatusFromString(statusStr)
|
||||
if err != nil {
|
||||
return nil, query.NewConverterError("invalid ExecutionStatus %q", statusStr)
|
||||
}
|
||||
vi.filter.Status = int32(e)
|
||||
}
|
||||
return values, err
|
||||
case searchattribute.StartTime:
|
||||
if len(values) != 2 {
|
||||
return nil, query.NewConverterError("StartTime only supports BETWEEN ... AND ... filter")
|
||||
}
|
||||
|
||||
values, err := vi.nextInterceptor.Values(name, values...)
|
||||
if err == nil {
|
||||
minTime, err := time.Parse(time.RFC3339Nano, values[0].(string))
|
||||
if err != nil {
|
||||
return nil, query.NewConverterError("invalid StartTime format: %v", minTime)
|
||||
}
|
||||
vi.filter.MinTime = &minTime
|
||||
|
||||
maxTime, err := time.Parse(time.RFC3339Nano, values[1].(string))
|
||||
if err != nil {
|
||||
return nil, query.NewConverterError("invalid StartTime format: %v", maxTime)
|
||||
}
|
||||
vi.filter.MaxTime = &maxTime
|
||||
}
|
||||
return values, err
|
||||
default:
|
||||
return nil, query.NewConverterError("filter by '%v' not supported for standard visibility", name)
|
||||
}
|
||||
}
|
||||
@@ -1,446 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package sql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
enumspb "go.temporal.io/api/enums/v1"
|
||||
"go.temporal.io/api/serviceerror"
|
||||
|
||||
"go.temporal.io/server/common/config"
|
||||
"go.temporal.io/server/common/log"
|
||||
"go.temporal.io/server/common/persistence"
|
||||
persistencesql "go.temporal.io/server/common/persistence/sql"
|
||||
"go.temporal.io/server/common/persistence/sql/sqlplugin"
|
||||
"go.temporal.io/server/common/persistence/visibility/manager"
|
||||
"go.temporal.io/server/common/persistence/visibility/store"
|
||||
"go.temporal.io/server/common/resolver"
|
||||
)
|
||||
|
||||
type (
|
||||
visibilityStore struct {
|
||||
sqlStore persistencesql.SqlStore
|
||||
}
|
||||
|
||||
visibilityPageToken struct {
|
||||
Time time.Time
|
||||
RunID string
|
||||
}
|
||||
)
|
||||
|
||||
var _ store.VisibilityStore = (*visibilityStore)(nil)
|
||||
|
||||
// NewSQLVisibilityStore creates an instance of VisibilityStore
|
||||
func NewSQLVisibilityStore(
|
||||
cfg config.SQL,
|
||||
r resolver.ServiceResolver,
|
||||
logger log.Logger,
|
||||
) (*visibilityStore, error) {
|
||||
refDbConn := persistencesql.NewRefCountedDBConn(sqlplugin.DbKindVisibility, &cfg, r)
|
||||
db, err := refDbConn.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &visibilityStore{
|
||||
sqlStore: persistencesql.NewSqlStore(db, logger),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *visibilityStore) Close() {
|
||||
s.sqlStore.Close()
|
||||
}
|
||||
|
||||
func (s *visibilityStore) GetName() string {
|
||||
return s.sqlStore.GetName()
|
||||
}
|
||||
|
||||
func (s *visibilityStore) GetIndexName() string {
|
||||
// GetIndexName is used to get cluster metadata, which in verstions < v1.20
|
||||
// were stored in an empty string key.
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *visibilityStore) ValidateCustomSearchAttributes(
|
||||
searchAttributes map[string]any,
|
||||
) (map[string]any, error) {
|
||||
return searchAttributes, nil
|
||||
}
|
||||
|
||||
func (s *visibilityStore) RecordWorkflowExecutionStarted(
|
||||
ctx context.Context,
|
||||
request *store.InternalRecordWorkflowExecutionStartedRequest,
|
||||
) error {
|
||||
_, err := s.sqlStore.Db.InsertIntoVisibility(ctx, &sqlplugin.VisibilityRow{
|
||||
NamespaceID: request.NamespaceID,
|
||||
WorkflowID: request.WorkflowID,
|
||||
RunID: request.RunID,
|
||||
StartTime: request.StartTime,
|
||||
ExecutionTime: request.ExecutionTime,
|
||||
WorkflowTypeName: request.WorkflowTypeName,
|
||||
Status: int32(enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING), // Underlying value (1) is hardcoded in SQL queries.
|
||||
Memo: request.Memo.Data,
|
||||
Encoding: request.Memo.EncodingType.String(),
|
||||
TaskQueue: request.TaskQueue,
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *visibilityStore) RecordWorkflowExecutionClosed(
|
||||
ctx context.Context,
|
||||
request *store.InternalRecordWorkflowExecutionClosedRequest,
|
||||
) error {
|
||||
result, err := s.sqlStore.Db.ReplaceIntoVisibility(ctx, &sqlplugin.VisibilityRow{
|
||||
NamespaceID: request.NamespaceID,
|
||||
WorkflowID: request.WorkflowID,
|
||||
RunID: request.RunID,
|
||||
StartTime: request.StartTime,
|
||||
ExecutionTime: request.ExecutionTime,
|
||||
WorkflowTypeName: request.WorkflowTypeName,
|
||||
CloseTime: &request.CloseTime,
|
||||
Status: int32(request.Status),
|
||||
HistoryLength: &request.HistoryLength,
|
||||
Memo: request.Memo.Data,
|
||||
Encoding: request.Memo.EncodingType.String(),
|
||||
TaskQueue: request.TaskQueue,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
noRowsAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return fmt.Errorf("RecordWorkflowExecutionClosed rowsAffected error: %v", err)
|
||||
}
|
||||
if noRowsAffected > 2 { // either adds a new row or deletes old row and adds new row
|
||||
return fmt.Errorf("RecordWorkflowExecutionClosed unexpected numRows (%v) updated", noRowsAffected)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *visibilityStore) UpsertWorkflowExecution(
|
||||
_ context.Context,
|
||||
_ *store.InternalUpsertWorkflowExecutionRequest,
|
||||
) error {
|
||||
// Not OperationNotSupportedErr!
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *visibilityStore) ListOpenWorkflowExecutions(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.listWorkflowExecutions(
|
||||
"ListOpenWorkflowExecutions",
|
||||
request.NextPageToken,
|
||||
request.PageSize,
|
||||
request.LatestStartTime,
|
||||
false,
|
||||
func(readLevel *visibilityPageToken) ([]sqlplugin.VisibilityRow, error) {
|
||||
return s.sqlStore.Db.SelectFromVisibility(ctx, sqlplugin.VisibilitySelectFilter{
|
||||
NamespaceID: request.NamespaceID.String(),
|
||||
MinTime: &request.EarliestStartTime,
|
||||
MaxTime: &readLevel.Time,
|
||||
RunID: &readLevel.RunID,
|
||||
PageSize: &request.PageSize,
|
||||
Status: int32(enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *visibilityStore) ListClosedWorkflowExecutions(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.listWorkflowExecutions("ListClosedWorkflowExecutions",
|
||||
request.NextPageToken,
|
||||
request.PageSize,
|
||||
request.LatestStartTime,
|
||||
true,
|
||||
func(readLevel *visibilityPageToken) ([]sqlplugin.VisibilityRow, error) {
|
||||
return s.sqlStore.Db.SelectFromVisibility(ctx, sqlplugin.VisibilitySelectFilter{
|
||||
NamespaceID: request.NamespaceID.String(),
|
||||
MinTime: &request.EarliestStartTime,
|
||||
MaxTime: &readLevel.Time,
|
||||
RunID: &readLevel.RunID,
|
||||
PageSize: &request.PageSize,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *visibilityStore) ListOpenWorkflowExecutionsByType(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsByTypeRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.listWorkflowExecutions("ListOpenWorkflowExecutionsByType",
|
||||
request.NextPageToken,
|
||||
request.PageSize,
|
||||
request.LatestStartTime,
|
||||
false,
|
||||
func(readLevel *visibilityPageToken) ([]sqlplugin.VisibilityRow, error) {
|
||||
return s.sqlStore.Db.SelectFromVisibility(ctx, sqlplugin.VisibilitySelectFilter{
|
||||
NamespaceID: request.NamespaceID.String(),
|
||||
MinTime: &request.EarliestStartTime,
|
||||
MaxTime: &readLevel.Time,
|
||||
RunID: &readLevel.RunID,
|
||||
WorkflowTypeName: &request.WorkflowTypeName,
|
||||
PageSize: &request.PageSize,
|
||||
Status: int32(enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *visibilityStore) ListClosedWorkflowExecutionsByType(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsByTypeRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.listWorkflowExecutions("ListClosedWorkflowExecutionsByType",
|
||||
request.NextPageToken,
|
||||
request.PageSize,
|
||||
request.LatestStartTime,
|
||||
true,
|
||||
func(readLevel *visibilityPageToken) ([]sqlplugin.VisibilityRow, error) {
|
||||
return s.sqlStore.Db.SelectFromVisibility(ctx, sqlplugin.VisibilitySelectFilter{
|
||||
NamespaceID: request.NamespaceID.String(),
|
||||
MinTime: &request.EarliestStartTime,
|
||||
MaxTime: &readLevel.Time,
|
||||
RunID: &readLevel.RunID,
|
||||
WorkflowTypeName: &request.WorkflowTypeName,
|
||||
PageSize: &request.PageSize,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *visibilityStore) ListOpenWorkflowExecutionsByWorkflowID(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsByWorkflowIDRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.listWorkflowExecutions("ListOpenWorkflowExecutionsByWorkflowID",
|
||||
request.NextPageToken,
|
||||
request.PageSize,
|
||||
request.LatestStartTime,
|
||||
false,
|
||||
func(readLevel *visibilityPageToken) ([]sqlplugin.VisibilityRow, error) {
|
||||
return s.sqlStore.Db.SelectFromVisibility(ctx, sqlplugin.VisibilitySelectFilter{
|
||||
NamespaceID: request.NamespaceID.String(),
|
||||
MinTime: &request.EarliestStartTime,
|
||||
MaxTime: &readLevel.Time,
|
||||
RunID: &readLevel.RunID,
|
||||
WorkflowID: &request.WorkflowID,
|
||||
PageSize: &request.PageSize,
|
||||
Status: int32(enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *visibilityStore) ListClosedWorkflowExecutionsByWorkflowID(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsByWorkflowIDRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.listWorkflowExecutions("ListClosedWorkflowExecutionsByWorkflowID",
|
||||
request.NextPageToken,
|
||||
request.PageSize,
|
||||
request.LatestStartTime,
|
||||
true,
|
||||
func(readLevel *visibilityPageToken) ([]sqlplugin.VisibilityRow, error) {
|
||||
return s.sqlStore.Db.SelectFromVisibility(ctx, sqlplugin.VisibilitySelectFilter{
|
||||
NamespaceID: request.NamespaceID.String(),
|
||||
MinTime: &request.EarliestStartTime,
|
||||
MaxTime: &readLevel.Time,
|
||||
RunID: &readLevel.RunID,
|
||||
WorkflowID: &request.WorkflowID,
|
||||
PageSize: &request.PageSize,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *visibilityStore) ListClosedWorkflowExecutionsByStatus(
|
||||
ctx context.Context,
|
||||
request *manager.ListClosedWorkflowExecutionsByStatusRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.listWorkflowExecutions("ListClosedWorkflowExecutionsByStatus",
|
||||
request.NextPageToken,
|
||||
request.PageSize,
|
||||
request.LatestStartTime,
|
||||
true,
|
||||
func(readLevel *visibilityPageToken) ([]sqlplugin.VisibilityRow, error) {
|
||||
return s.sqlStore.Db.SelectFromVisibility(ctx, sqlplugin.VisibilitySelectFilter{
|
||||
NamespaceID: request.NamespaceID.String(),
|
||||
MinTime: &request.EarliestStartTime,
|
||||
MaxTime: &readLevel.Time,
|
||||
RunID: &readLevel.RunID,
|
||||
Status: int32(request.Status),
|
||||
PageSize: &request.PageSize,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *visibilityStore) DeleteWorkflowExecution(
|
||||
ctx context.Context,
|
||||
request *manager.VisibilityDeleteWorkflowExecutionRequest,
|
||||
) error {
|
||||
_, err := s.sqlStore.Db.DeleteFromVisibility(ctx, sqlplugin.VisibilityDeleteFilter{
|
||||
NamespaceID: request.NamespaceID.String(),
|
||||
RunID: request.RunID,
|
||||
})
|
||||
if err != nil {
|
||||
return serviceerror.NewUnavailable(err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *visibilityStore) ListWorkflowExecutions(
|
||||
_ context.Context,
|
||||
_ *manager.ListWorkflowExecutionsRequestV2,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return nil, store.OperationNotSupportedErr
|
||||
}
|
||||
|
||||
func (s *visibilityStore) ScanWorkflowExecutions(
|
||||
_ context.Context,
|
||||
_ *manager.ListWorkflowExecutionsRequestV2,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return nil, store.OperationNotSupportedErr
|
||||
}
|
||||
|
||||
func (s *visibilityStore) CountWorkflowExecutions(
|
||||
_ context.Context,
|
||||
_ *manager.CountWorkflowExecutionsRequest,
|
||||
) (*manager.CountWorkflowExecutionsResponse, error) {
|
||||
return nil, store.OperationNotSupportedErr
|
||||
}
|
||||
|
||||
func (s *visibilityStore) GetWorkflowExecution(
|
||||
ctx context.Context,
|
||||
request *manager.GetWorkflowExecutionRequest,
|
||||
) (*store.InternalGetWorkflowExecutionResponse, error) {
|
||||
row, err := s.sqlStore.Db.GetFromVisibility(ctx, sqlplugin.VisibilityGetFilter{
|
||||
NamespaceID: request.NamespaceID.String(),
|
||||
RunID: request.RunID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, serviceerror.NewUnavailable(
|
||||
fmt.Sprintf("GetWorkflowExecution operation failed. Select failed: %v", err))
|
||||
}
|
||||
return &store.InternalGetWorkflowExecutionResponse{
|
||||
Execution: s.rowToInfo(row),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *visibilityStore) rowToInfo(
|
||||
row *sqlplugin.VisibilityRow,
|
||||
) *store.InternalWorkflowExecutionInfo {
|
||||
if row.ExecutionTime.UnixNano() == 0 {
|
||||
row.ExecutionTime = row.StartTime
|
||||
}
|
||||
info := &store.InternalWorkflowExecutionInfo{
|
||||
WorkflowID: row.WorkflowID,
|
||||
RunID: row.RunID,
|
||||
TypeName: row.WorkflowTypeName,
|
||||
StartTime: row.StartTime,
|
||||
ExecutionTime: row.ExecutionTime,
|
||||
Memo: persistence.NewDataBlob(row.Memo, row.Encoding),
|
||||
Status: enumspb.WorkflowExecutionStatus(row.Status),
|
||||
TaskQueue: row.TaskQueue,
|
||||
}
|
||||
if row.CloseTime != nil {
|
||||
info.CloseTime = *row.CloseTime
|
||||
info.HistoryLength = *row.HistoryLength
|
||||
}
|
||||
if row.HistoryLength != nil {
|
||||
info.HistoryLength = *row.HistoryLength
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
func (s *visibilityStore) listWorkflowExecutions(
|
||||
opName string,
|
||||
pageToken []byte,
|
||||
pageSize int,
|
||||
latestTime time.Time,
|
||||
closeQuery bool,
|
||||
selectOp func(readLevel *visibilityPageToken) ([]sqlplugin.VisibilityRow, error),
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
var readLevel *visibilityPageToken
|
||||
var err error
|
||||
if len(pageToken) > 0 {
|
||||
readLevel, err = s.deserializePageToken(pageToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
readLevel = &visibilityPageToken{Time: latestTime, RunID: ""}
|
||||
}
|
||||
rows, err := selectOp(readLevel)
|
||||
if err != nil {
|
||||
return nil, serviceerror.NewUnavailable(fmt.Sprintf("%v operation failed. Select failed: %v", opName, err))
|
||||
}
|
||||
if len(rows) == 0 {
|
||||
return &store.InternalListWorkflowExecutionsResponse{}, nil
|
||||
}
|
||||
|
||||
var infos = make([]*store.InternalWorkflowExecutionInfo, len(rows))
|
||||
for i, row := range rows {
|
||||
infos[i] = s.rowToInfo(&row)
|
||||
}
|
||||
|
||||
var nextPageToken []byte
|
||||
if len(rows) == pageSize {
|
||||
lastRow := rows[len(rows)-1]
|
||||
lastTime := lastRow.StartTime
|
||||
if closeQuery {
|
||||
lastTime = *lastRow.CloseTime
|
||||
}
|
||||
nextPageToken, err = s.serializePageToken(&visibilityPageToken{
|
||||
Time: lastTime,
|
||||
RunID: lastRow.RunID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &store.InternalListWorkflowExecutionsResponse{
|
||||
Executions: infos,
|
||||
NextPageToken: nextPageToken,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *visibilityStore) deserializePageToken(
|
||||
data []byte,
|
||||
) (*visibilityPageToken, error) {
|
||||
var token visibilityPageToken
|
||||
err := json.Unmarshal(data, &token)
|
||||
return &token, err
|
||||
}
|
||||
|
||||
func (s *visibilityStore) serializePageToken(
|
||||
token *visibilityPageToken,
|
||||
) ([]byte, error) {
|
||||
data, err := json.Marshal(token)
|
||||
return data, err
|
||||
}
|
||||
@@ -1,401 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2021 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package standard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
enumspb "go.temporal.io/api/enums/v1"
|
||||
|
||||
"go.temporal.io/server/common/persistence/visibility/manager"
|
||||
"go.temporal.io/server/common/persistence/visibility/store"
|
||||
"go.temporal.io/server/common/searchattribute"
|
||||
)
|
||||
|
||||
type (
|
||||
standardStore struct {
|
||||
store store.VisibilityStore
|
||||
searchAttributesProvider searchattribute.Provider
|
||||
searchAttributesMapperProvider searchattribute.MapperProvider
|
||||
}
|
||||
|
||||
// We wrap the token with a boolean to indicate if it is from list open workflows or list closed workflows,
|
||||
// so we know where to continue from for the next call.
|
||||
nextPageToken struct {
|
||||
ForOpenWorkflows bool `json:"isOpen"`
|
||||
Token []byte
|
||||
}
|
||||
|
||||
listRequest interface {
|
||||
OverrideToken(token []byte)
|
||||
GetToken() []byte
|
||||
OverridePageSize(pageSize int)
|
||||
GetPageSize() int
|
||||
}
|
||||
)
|
||||
|
||||
var _ store.VisibilityStore = (*standardStore)(nil)
|
||||
var _ listRequest = (*manager.ListWorkflowExecutionsRequest)(nil)
|
||||
|
||||
func NewVisibilityStore(
|
||||
visibilityStore store.VisibilityStore,
|
||||
searchAttributesProvider searchattribute.Provider,
|
||||
searchAttributesMapperProvider searchattribute.MapperProvider,
|
||||
) store.VisibilityStore {
|
||||
return &standardStore{
|
||||
store: visibilityStore,
|
||||
searchAttributesProvider: searchAttributesProvider,
|
||||
searchAttributesMapperProvider: searchAttributesMapperProvider,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *standardStore) Close() {
|
||||
s.store.Close()
|
||||
}
|
||||
|
||||
func (s *standardStore) GetName() string {
|
||||
return s.store.GetName()
|
||||
}
|
||||
|
||||
func (s *standardStore) GetIndexName() string {
|
||||
// GetIndexName is used to get cluster metadata, which in verstions < v1.20
|
||||
// were stored in an empty string key.
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *standardStore) ValidateCustomSearchAttributes(
|
||||
searchAttributes map[string]any,
|
||||
) (map[string]any, error) {
|
||||
return searchAttributes, nil
|
||||
}
|
||||
|
||||
func (s *standardStore) RecordWorkflowExecutionStarted(
|
||||
ctx context.Context,
|
||||
request *store.InternalRecordWorkflowExecutionStartedRequest,
|
||||
) error {
|
||||
return s.store.RecordWorkflowExecutionStarted(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) RecordWorkflowExecutionClosed(
|
||||
ctx context.Context,
|
||||
request *store.InternalRecordWorkflowExecutionClosedRequest,
|
||||
) error {
|
||||
return s.store.RecordWorkflowExecutionClosed(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) UpsertWorkflowExecution(
|
||||
ctx context.Context,
|
||||
request *store.InternalUpsertWorkflowExecutionRequest,
|
||||
) error {
|
||||
return s.store.UpsertWorkflowExecution(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) DeleteWorkflowExecution(
|
||||
ctx context.Context,
|
||||
request *manager.VisibilityDeleteWorkflowExecutionRequest,
|
||||
) error {
|
||||
return s.store.DeleteWorkflowExecution(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) ListOpenWorkflowExecutions(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.store.ListOpenWorkflowExecutions(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) ListClosedWorkflowExecutions(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.store.ListClosedWorkflowExecutions(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) ListOpenWorkflowExecutionsByType(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsByTypeRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.store.ListOpenWorkflowExecutionsByType(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) ListClosedWorkflowExecutionsByType(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsByTypeRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.store.ListClosedWorkflowExecutionsByType(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) ListOpenWorkflowExecutionsByWorkflowID(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsByWorkflowIDRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.store.ListOpenWorkflowExecutionsByWorkflowID(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) ListClosedWorkflowExecutionsByWorkflowID(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsByWorkflowIDRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.store.ListClosedWorkflowExecutionsByWorkflowID(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) ListClosedWorkflowExecutionsByStatus(
|
||||
ctx context.Context,
|
||||
request *manager.ListClosedWorkflowExecutionsByStatusRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.store.ListClosedWorkflowExecutionsByStatus(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) ScanWorkflowExecutions(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsRequestV2,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
return s.store.ScanWorkflowExecutions(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) CountWorkflowExecutions(
|
||||
ctx context.Context,
|
||||
request *manager.CountWorkflowExecutionsRequest,
|
||||
) (*manager.CountWorkflowExecutionsResponse, error) {
|
||||
return s.store.CountWorkflowExecutions(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) GetWorkflowExecution(
|
||||
ctx context.Context,
|
||||
request *manager.GetWorkflowExecutionRequest,
|
||||
) (*store.InternalGetWorkflowExecutionResponse, error) {
|
||||
return s.store.GetWorkflowExecution(ctx, request)
|
||||
}
|
||||
|
||||
func (s *standardStore) ListWorkflowExecutions(
|
||||
ctx context.Context,
|
||||
request *manager.ListWorkflowExecutionsRequestV2,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
typeMap, err := s.searchAttributesProvider.GetSearchAttributes(s.GetIndexName(), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
converter := newQueryConverter(request.Namespace, typeMap, s.searchAttributesMapperProvider)
|
||||
filter, err := converter.GetFilter(request.Query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
baseReq := &manager.ListWorkflowExecutionsRequest{
|
||||
NamespaceID: request.NamespaceID,
|
||||
Namespace: request.Namespace,
|
||||
PageSize: request.PageSize,
|
||||
NextPageToken: request.NextPageToken,
|
||||
EarliestStartTime: *filter.MinTime,
|
||||
LatestStartTime: *filter.MaxTime,
|
||||
}
|
||||
|
||||
// Only a limited query patterns are supported due to the way we set up
|
||||
// visibility tables in Cassandra.
|
||||
// Check validation logic in query interceptor for details.
|
||||
if filter.WorkflowID != nil {
|
||||
request := &manager.ListWorkflowExecutionsByWorkflowIDRequest{
|
||||
ListWorkflowExecutionsRequest: baseReq,
|
||||
WorkflowID: *filter.WorkflowID,
|
||||
}
|
||||
return s.listWorkflowExecutionsHelper(
|
||||
ctx,
|
||||
request,
|
||||
s.listOpenWorkflowExecutionsByWorkflowID,
|
||||
s.listClosedWorkflowExecutionsByWorkflowID)
|
||||
} else if filter.WorkflowTypeName != nil {
|
||||
request := &manager.ListWorkflowExecutionsByTypeRequest{
|
||||
ListWorkflowExecutionsRequest: baseReq,
|
||||
WorkflowTypeName: *filter.WorkflowTypeName,
|
||||
}
|
||||
return s.listWorkflowExecutionsHelper(
|
||||
ctx,
|
||||
request,
|
||||
s.listOpenWorkflowExecutionsByType,
|
||||
s.listClosedWorkflowExecutionsByType)
|
||||
} else if filter.Status != int32(enumspb.WORKFLOW_EXECUTION_STATUS_UNSPECIFIED) {
|
||||
if filter.Status == int32(enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING) {
|
||||
return s.ListOpenWorkflowExecutions(ctx, baseReq)
|
||||
} else {
|
||||
request := &manager.ListClosedWorkflowExecutionsByStatusRequest{
|
||||
ListWorkflowExecutionsRequest: baseReq,
|
||||
Status: enumspb.WorkflowExecutionStatus(filter.Status),
|
||||
}
|
||||
return s.ListClosedWorkflowExecutionsByStatus(ctx, request)
|
||||
}
|
||||
} else {
|
||||
return s.listWorkflowExecutionsHelper(
|
||||
ctx,
|
||||
baseReq,
|
||||
s.listOpenWorkflowExecutions,
|
||||
s.listClosedWorkflowExecutions)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *standardStore) listWorkflowExecutionsHelper(
|
||||
ctx context.Context,
|
||||
request listRequest,
|
||||
listOpenFunc func(ctx context.Context, request listRequest) (*store.InternalListWorkflowExecutionsResponse, error),
|
||||
listCloseFunc func(ctx context.Context, request listRequest) (*store.InternalListWorkflowExecutionsResponse, error),
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
|
||||
var token nextPageToken
|
||||
if len(request.GetToken()) == 0 {
|
||||
token = nextPageToken{
|
||||
ForOpenWorkflows: true,
|
||||
}
|
||||
} else {
|
||||
err := json.Unmarshal(request.GetToken(), &token)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid next page token: %v", err)
|
||||
}
|
||||
request.OverrideToken(token.Token)
|
||||
}
|
||||
|
||||
resp := &store.InternalListWorkflowExecutionsResponse{}
|
||||
|
||||
if token.ForOpenWorkflows {
|
||||
listOpenResp, err := listOpenFunc(ctx, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(listOpenResp.Executions) > 0 {
|
||||
request.OverridePageSize(request.GetPageSize() - len(listOpenResp.Executions))
|
||||
resp.Executions = append(resp.Executions, listOpenResp.Executions...)
|
||||
}
|
||||
|
||||
if request.GetPageSize() == 0 {
|
||||
token.Token = listOpenResp.NextPageToken
|
||||
|
||||
token, err := json.Marshal(token)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal next page token: %v", err)
|
||||
}
|
||||
|
||||
resp.NextPageToken = token
|
||||
return resp, nil
|
||||
} else {
|
||||
token.ForOpenWorkflows = false
|
||||
request.OverrideToken(nil)
|
||||
}
|
||||
}
|
||||
|
||||
listCloseResp, err := listCloseFunc(ctx, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.Executions = append(resp.Executions, listCloseResp.Executions...)
|
||||
|
||||
if listCloseResp.NextPageToken == nil {
|
||||
resp.NextPageToken = nil
|
||||
} else {
|
||||
token.Token = listCloseResp.NextPageToken
|
||||
token, err := json.Marshal(token)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal next page token: %v", err)
|
||||
}
|
||||
|
||||
resp.NextPageToken = token
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *standardStore) listOpenWorkflowExecutionsByWorkflowID(
|
||||
ctx context.Context,
|
||||
request listRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
actualRequest, ok := request.(*manager.ListWorkflowExecutionsByWorkflowIDRequest)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("wrong request type %v for listOpenWorkflowExecutionsByWorkflowID", reflect.TypeOf(request)))
|
||||
}
|
||||
|
||||
return s.ListOpenWorkflowExecutionsByWorkflowID(ctx, actualRequest)
|
||||
}
|
||||
|
||||
func (s *standardStore) listOpenWorkflowExecutionsByType(
|
||||
ctx context.Context,
|
||||
request listRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
actualRequest, ok := request.(*manager.ListWorkflowExecutionsByTypeRequest)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("wrong request type %v for listOpenWorkflowExecutionsByType", reflect.TypeOf(request)))
|
||||
}
|
||||
|
||||
return s.ListOpenWorkflowExecutionsByType(ctx, actualRequest)
|
||||
}
|
||||
|
||||
func (s *standardStore) listOpenWorkflowExecutions(
|
||||
ctx context.Context,
|
||||
request listRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
actualRequest, ok := request.(*manager.ListWorkflowExecutionsRequest)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("wrong request type %v for listOpenWorkflowExecutions", reflect.TypeOf(request)))
|
||||
}
|
||||
|
||||
return s.ListOpenWorkflowExecutions(ctx, actualRequest)
|
||||
}
|
||||
|
||||
func (s *standardStore) listClosedWorkflowExecutionsByWorkflowID(
|
||||
ctx context.Context,
|
||||
request listRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
actualRequest, ok := request.(*manager.ListWorkflowExecutionsByWorkflowIDRequest)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("wrong request type %v for listClosedWorkflowExecutionsByWorkflowID", reflect.TypeOf(request)))
|
||||
}
|
||||
|
||||
return s.ListClosedWorkflowExecutionsByWorkflowID(ctx, actualRequest)
|
||||
}
|
||||
|
||||
func (s *standardStore) listClosedWorkflowExecutionsByType(
|
||||
ctx context.Context,
|
||||
request listRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
actualRequest, ok := request.(*manager.ListWorkflowExecutionsByTypeRequest)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("wrong request type %v for listClosedWorkflowExecutionsByType", reflect.TypeOf(request)))
|
||||
}
|
||||
|
||||
return s.ListClosedWorkflowExecutionsByType(ctx, actualRequest)
|
||||
}
|
||||
|
||||
func (s *standardStore) listClosedWorkflowExecutions(
|
||||
ctx context.Context,
|
||||
request listRequest,
|
||||
) (*store.InternalListWorkflowExecutionsResponse, error) {
|
||||
actualRequest, ok := request.(*manager.ListWorkflowExecutionsRequest)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("wrong request type %v for listClosedWorkflowExecutions", reflect.TypeOf(request)))
|
||||
}
|
||||
|
||||
return s.ListClosedWorkflowExecutions(ctx, actualRequest)
|
||||
}
|
||||
@@ -9,7 +9,7 @@ persistence:
|
||||
datastores:
|
||||
mysql-default:
|
||||
sql:
|
||||
pluginName: "mysql"
|
||||
pluginName: "mysql8"
|
||||
databaseName: "temporal"
|
||||
connectAddr: "127.0.0.1:3306"
|
||||
connectProtocol: "tcp"
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
log:
|
||||
stdout: true
|
||||
level: info
|
||||
|
||||
persistence:
|
||||
defaultStore: mysql-default
|
||||
visibilityStore: mysql-visibility
|
||||
numHistoryShards: 4
|
||||
datastores:
|
||||
mysql-default:
|
||||
sql:
|
||||
pluginName: "mysql"
|
||||
databaseName: "temporal"
|
||||
connectAddr: "127.0.0.1:3306"
|
||||
connectProtocol: "tcp"
|
||||
user: "temporal"
|
||||
password: "temporal"
|
||||
maxConns: 20
|
||||
maxIdleConns: 20
|
||||
maxConnLifetime: "1h"
|
||||
mysql-visibility:
|
||||
sql:
|
||||
pluginName: "mysql"
|
||||
databaseName: "temporal_visibility"
|
||||
connectAddr: "127.0.0.1:3306"
|
||||
connectProtocol: "tcp"
|
||||
user: "temporal"
|
||||
password: "temporal"
|
||||
maxConns: 2
|
||||
maxIdleConns: 2
|
||||
maxConnLifetime: "1h"
|
||||
|
||||
global:
|
||||
membership:
|
||||
maxJoinDuration: 30s
|
||||
broadcastAddress: "127.0.0.1"
|
||||
pprof:
|
||||
port: 7936
|
||||
metrics:
|
||||
prometheus:
|
||||
# # specify framework to use new approach for initializing metrics and/or use opentelemetry
|
||||
# framework: "opentelemetry"
|
||||
framework: "tally"
|
||||
timerType: "histogram"
|
||||
listenAddress: "127.0.0.1:8000"
|
||||
|
||||
services:
|
||||
frontend:
|
||||
rpc:
|
||||
grpcPort: 7233
|
||||
membershipPort: 6933
|
||||
bindOnLocalHost: true
|
||||
httpPort: 7243
|
||||
|
||||
matching:
|
||||
rpc:
|
||||
grpcPort: 7235
|
||||
membershipPort: 6935
|
||||
bindOnLocalHost: true
|
||||
|
||||
history:
|
||||
rpc:
|
||||
grpcPort: 7234
|
||||
membershipPort: 6934
|
||||
bindOnLocalHost: true
|
||||
|
||||
worker:
|
||||
rpc:
|
||||
grpcPort: 7239
|
||||
membershipPort: 6939
|
||||
bindOnLocalHost: true
|
||||
|
||||
clusterMetadata:
|
||||
enableGlobalNamespace: false
|
||||
failoverVersionIncrement: 10
|
||||
masterClusterName: "active"
|
||||
currentClusterName: "active"
|
||||
clusterInformation:
|
||||
active:
|
||||
enabled: true
|
||||
initialFailoverVersion: 1
|
||||
rpcName: "frontend"
|
||||
rpcAddress: "localhost:7233"
|
||||
|
||||
dcRedirectionPolicy:
|
||||
policy: "noop"
|
||||
|
||||
archival:
|
||||
history:
|
||||
state: "enabled"
|
||||
enableRead: true
|
||||
provider:
|
||||
filestore:
|
||||
fileMode: "0666"
|
||||
dirMode: "0766"
|
||||
gstorage:
|
||||
credentialsPath: "/tmp/gcloud/keyfile.json"
|
||||
visibility:
|
||||
state: "enabled"
|
||||
enableRead: true
|
||||
provider:
|
||||
filestore:
|
||||
fileMode: "0666"
|
||||
dirMode: "0766"
|
||||
|
||||
namespaceDefaults:
|
||||
archival:
|
||||
history:
|
||||
state: "disabled"
|
||||
URI: "file:///tmp/temporal_archival/development"
|
||||
visibility:
|
||||
state: "disabled"
|
||||
URI: "file:///tmp/temporal_vis_archival/development"
|
||||
|
||||
dynamicConfigClient:
|
||||
filepath: "config/dynamicconfig/development-sql.yaml"
|
||||
pollInterval: "10s"
|
||||
@@ -9,7 +9,7 @@ persistence:
|
||||
datastores:
|
||||
postgres-default:
|
||||
sql:
|
||||
pluginName: "postgres"
|
||||
pluginName: "postgres12"
|
||||
databaseName: "temporal"
|
||||
connectAddr: "127.0.0.1:5432"
|
||||
connectProtocol: "tcp"
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
log:
|
||||
stdout: true
|
||||
level: info
|
||||
|
||||
persistence:
|
||||
defaultStore: postgres-default
|
||||
visibilityStore: postgres-visibility
|
||||
numHistoryShards: 4
|
||||
datastores:
|
||||
postgres-default:
|
||||
sql:
|
||||
pluginName: "postgres"
|
||||
databaseName: "temporal"
|
||||
connectAddr: "127.0.0.1:5432"
|
||||
connectProtocol: "tcp"
|
||||
user: "temporal"
|
||||
password: "temporal"
|
||||
maxConns: 20
|
||||
maxIdleConns: 20
|
||||
maxConnLifetime: "1h"
|
||||
postgres-visibility:
|
||||
sql:
|
||||
pluginName: "postgres"
|
||||
databaseName: "temporal_visibility"
|
||||
connectAddr: "127.0.0.1:5432"
|
||||
connectProtocol: "tcp"
|
||||
user: "temporal"
|
||||
password: "temporal"
|
||||
maxConns: 2
|
||||
maxIdleConns: 2
|
||||
maxConnLifetime: "1h"
|
||||
|
||||
global:
|
||||
membership:
|
||||
maxJoinDuration: 30s
|
||||
broadcastAddress: "127.0.0.1"
|
||||
pprof:
|
||||
port: 7936
|
||||
metrics:
|
||||
prometheus:
|
||||
# # specify framework to use new approach for initializing metrics and/or use opentelemetry
|
||||
# framework: "opentelemetry"
|
||||
framework: "tally"
|
||||
timerType: "histogram"
|
||||
listenAddress: "127.0.0.1:8000"
|
||||
|
||||
services:
|
||||
frontend:
|
||||
rpc:
|
||||
grpcPort: 7233
|
||||
membershipPort: 6933
|
||||
bindOnLocalHost: true
|
||||
httpPort: 7243
|
||||
|
||||
matching:
|
||||
rpc:
|
||||
grpcPort: 7235
|
||||
membershipPort: 6935
|
||||
bindOnLocalHost: true
|
||||
|
||||
history:
|
||||
rpc:
|
||||
grpcPort: 7234
|
||||
membershipPort: 6934
|
||||
bindOnLocalHost: true
|
||||
|
||||
worker:
|
||||
rpc:
|
||||
grpcPort: 7239
|
||||
membershipPort: 6939
|
||||
bindOnLocalHost: true
|
||||
|
||||
clusterMetadata:
|
||||
enableGlobalNamespace: false
|
||||
failoverVersionIncrement: 10
|
||||
masterClusterName: "active"
|
||||
currentClusterName: "active"
|
||||
clusterInformation:
|
||||
active:
|
||||
enabled: true
|
||||
initialFailoverVersion: 1
|
||||
rpcName: "frontend"
|
||||
rpcAddress: "localhost:7233"
|
||||
|
||||
dcRedirectionPolicy:
|
||||
policy: "noop"
|
||||
|
||||
archival:
|
||||
history:
|
||||
state: "enabled"
|
||||
enableRead: true
|
||||
provider:
|
||||
filestore:
|
||||
fileMode: "0666"
|
||||
dirMode: "0766"
|
||||
gstorage:
|
||||
credentialsPath: "/tmp/gcloud/keyfile.json"
|
||||
visibility:
|
||||
state: "enabled"
|
||||
enableRead: true
|
||||
provider:
|
||||
filestore:
|
||||
fileMode: "0666"
|
||||
dirMode: "0766"
|
||||
|
||||
namespaceDefaults:
|
||||
archival:
|
||||
history:
|
||||
state: "disabled"
|
||||
URI: "file:///tmp/temporal_archival/development"
|
||||
visibility:
|
||||
state: "disabled"
|
||||
URI: "file:///tmp/temporal_vis_archival/development"
|
||||
|
||||
dynamicConfigClient:
|
||||
filepath: "config/dynamicconfig/development-sql.yaml"
|
||||
pollInterval: "10s"
|
||||
@@ -45,7 +45,7 @@ docker compose run integration-test-cassandra make integration-test-coverage
|
||||
```
|
||||
or run integration tests with MySQL:
|
||||
```bash
|
||||
docker compose run integration-test-mysql make integration-test-coverage
|
||||
docker compose run integration-test-mysql8 make integration-test-coverage
|
||||
```
|
||||
|
||||
## Testing the build in Buildkite
|
||||
|
||||
@@ -173,27 +173,6 @@ services:
|
||||
aliases:
|
||||
- integration-test
|
||||
|
||||
integration-test-mysql:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: ./develop/buildkite/Dockerfile
|
||||
environment:
|
||||
- "MYSQL_SEEDS=mysql"
|
||||
- "ES_SEEDS=elasticsearch"
|
||||
- "ES_VERSION=v7"
|
||||
- "PERSISTENCE_TYPE=sql"
|
||||
- "PERSISTENCE_DRIVER=mysql"
|
||||
- "TEMPORAL_VERSION_CHECK_DISABLED=1"
|
||||
depends_on:
|
||||
- mysql
|
||||
- elasticsearch
|
||||
volumes:
|
||||
- ../../.testoutput:/temporal/.testoutput
|
||||
networks:
|
||||
services-network:
|
||||
aliases:
|
||||
- integration-test
|
||||
|
||||
integration-test-mysql8:
|
||||
build:
|
||||
context: ../..
|
||||
@@ -212,48 +191,6 @@ services:
|
||||
aliases:
|
||||
- integration-test
|
||||
|
||||
integration-test-postgresql:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: ./develop/buildkite/Dockerfile
|
||||
environment:
|
||||
- "POSTGRES_SEEDS=postgresql"
|
||||
- "ES_SEEDS=elasticsearch"
|
||||
- "ES_VERSION=v7"
|
||||
- "PERSISTENCE_TYPE=sql"
|
||||
- "PERSISTENCE_DRIVER=postgres"
|
||||
- "TEMPORAL_VERSION_CHECK_DISABLED=1"
|
||||
depends_on:
|
||||
- postgresql
|
||||
- elasticsearch
|
||||
volumes:
|
||||
- ../../.testoutput:/temporal/.testoutput
|
||||
networks:
|
||||
services-network:
|
||||
aliases:
|
||||
- integration-test
|
||||
|
||||
integration-test-postgresql-pgx:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: ./develop/buildkite/Dockerfile
|
||||
environment:
|
||||
- "POSTGRES_SEEDS=postgresql"
|
||||
- "ES_SEEDS=elasticsearch"
|
||||
- "ES_VERSION=v7"
|
||||
- "PERSISTENCE_TYPE=sql"
|
||||
- "PERSISTENCE_DRIVER=postgres_pgx"
|
||||
- "TEMPORAL_VERSION_CHECK_DISABLED=1"
|
||||
depends_on:
|
||||
- postgresql
|
||||
- elasticsearch
|
||||
volumes:
|
||||
- ../../.testoutput:/temporal/.testoutput
|
||||
networks:
|
||||
services-network:
|
||||
aliases:
|
||||
- integration-test
|
||||
|
||||
integration-test-postgresql12:
|
||||
build:
|
||||
context: ../..
|
||||
@@ -327,28 +264,6 @@ services:
|
||||
aliases:
|
||||
- integration-test-xdc
|
||||
|
||||
integration-test-xdc-mysql:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: ./develop/buildkite/Dockerfile
|
||||
environment:
|
||||
- "MYSQL_SEEDS=mysql"
|
||||
- "ES_SEEDS=elasticsearch"
|
||||
- "ES_VERSION=v7"
|
||||
- "PERSISTENCE_TYPE=sql"
|
||||
- "PERSISTENCE_DRIVER=mysql"
|
||||
- "TEST_RUN_COUNT=10"
|
||||
- "TEMPORAL_VERSION_CHECK_DISABLED=1"
|
||||
depends_on:
|
||||
- mysql
|
||||
- elasticsearch
|
||||
volumes:
|
||||
- ../../.testoutput:/temporal/.testoutput
|
||||
networks:
|
||||
services-network:
|
||||
aliases:
|
||||
- integration-test-xdc
|
||||
|
||||
integration-test-xdc-mysql8:
|
||||
build:
|
||||
context: ../..
|
||||
@@ -368,50 +283,6 @@ services:
|
||||
aliases:
|
||||
- integration-test-xdc
|
||||
|
||||
integration-test-xdc-postgresql:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: ./develop/buildkite/Dockerfile
|
||||
environment:
|
||||
- "POSTGRES_SEEDS=postgresql"
|
||||
- "ES_SEEDS=elasticsearch"
|
||||
- "ES_VERSION=v7"
|
||||
- "PERSISTENCE_TYPE=sql"
|
||||
- "PERSISTENCE_DRIVER=postgres"
|
||||
- "TEST_RUN_COUNT=10"
|
||||
- "TEMPORAL_VERSION_CHECK_DISABLED=1"
|
||||
depends_on:
|
||||
- postgresql
|
||||
- elasticsearch
|
||||
volumes:
|
||||
- ../../.testoutput:/temporal/.testoutput
|
||||
networks:
|
||||
services-network:
|
||||
aliases:
|
||||
- integration-test-xdc
|
||||
|
||||
integration-test-xdc-postgresql-pgx:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: ./develop/buildkite/Dockerfile
|
||||
environment:
|
||||
- "POSTGRES_SEEDS=postgresql"
|
||||
- "ES_SEEDS=elasticsearch"
|
||||
- "ES_VERSION=v7"
|
||||
- "PERSISTENCE_TYPE=sql"
|
||||
- "PERSISTENCE_DRIVER=postgres_pgx"
|
||||
- "TEST_RUN_COUNT=10"
|
||||
- "TEMPORAL_VERSION_CHECK_DISABLED=1"
|
||||
depends_on:
|
||||
- postgresql
|
||||
- elasticsearch
|
||||
volumes:
|
||||
- ../../.testoutput:/temporal/.testoutput
|
||||
networks:
|
||||
services-network:
|
||||
aliases:
|
||||
- integration-test-xdc
|
||||
|
||||
integration-test-xdc-postgresql12:
|
||||
build:
|
||||
context: ../..
|
||||
|
||||
@@ -17,10 +17,7 @@ steps:
|
||||
- integration-test-cassandra
|
||||
- integration-test-cassandra-es8
|
||||
- integration-test-cassandra-opensearch
|
||||
- integration-test-mysql
|
||||
- integration-test-mysql8
|
||||
- integration-test-postgresql
|
||||
- integration-test-postgresql-pgx
|
||||
- integration-test-postgresql12
|
||||
- integration-test-postgresql12-pgx
|
||||
- integration-test-sqlite
|
||||
@@ -204,70 +201,6 @@ steps:
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional test with mysql"
|
||||
agents:
|
||||
queue: "default"
|
||||
docker: "*"
|
||||
command: "make functional-test-coverage"
|
||||
parallelism: 3
|
||||
artifact_paths:
|
||||
- ".testoutput/*"
|
||||
retry:
|
||||
automatic:
|
||||
limit: 1
|
||||
plugins:
|
||||
- artifacts#v1.9.0:
|
||||
download: "develop/buildkite/*"
|
||||
- ecr#v2.7.0: {login: true}
|
||||
- docker-compose#v4.14.0:
|
||||
run: integration-test-mysql
|
||||
config: ./develop/buildkite/docker-compose.yml
|
||||
skip-checkout: true
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional xdc test with mysql"
|
||||
agents:
|
||||
queue: "default"
|
||||
docker: "*"
|
||||
command: "make functional-test-xdc-coverage"
|
||||
artifact_paths:
|
||||
- ".testoutput/*"
|
||||
retry:
|
||||
automatic:
|
||||
limit: 1
|
||||
plugins:
|
||||
- artifacts#v1.9.0:
|
||||
download: "develop/buildkite/*"
|
||||
- ecr#v2.7.0: {login: true}
|
||||
- docker-compose#v4.14.0:
|
||||
run: integration-test-xdc-mysql
|
||||
config: ./develop/buildkite/docker-compose.yml
|
||||
skip-checkout: true
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional ndc test with mysql"
|
||||
agents:
|
||||
queue: "default"
|
||||
docker: "*"
|
||||
command: "make functional-test-ndc-coverage"
|
||||
artifact_paths:
|
||||
- ".testoutput/*"
|
||||
retry:
|
||||
automatic:
|
||||
limit: 1
|
||||
plugins:
|
||||
- artifacts#v1.9.0:
|
||||
download: "develop/buildkite/*"
|
||||
- ecr#v2.7.0: {login: true}
|
||||
- docker-compose#v4.14.0:
|
||||
run: integration-test-xdc-mysql
|
||||
config: ./develop/buildkite/docker-compose.yml
|
||||
skip-checkout: true
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional test with mysql 8"
|
||||
agents:
|
||||
queue: "default"
|
||||
@@ -332,134 +265,6 @@ steps:
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional test with postgresql"
|
||||
agents:
|
||||
queue: "default"
|
||||
docker: "*"
|
||||
command: "make functional-test-coverage"
|
||||
parallelism: 3
|
||||
artifact_paths:
|
||||
- ".testoutput/*"
|
||||
retry:
|
||||
automatic:
|
||||
limit: 1
|
||||
plugins:
|
||||
- artifacts#v1.9.0:
|
||||
download: "develop/buildkite/*"
|
||||
- ecr#v2.7.0: {login: true}
|
||||
- docker-compose#v4.14.0:
|
||||
run: integration-test-postgresql
|
||||
config: ./develop/buildkite/docker-compose.yml
|
||||
skip-checkout: true
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional xdc test with postgresql"
|
||||
agents:
|
||||
queue: "default"
|
||||
docker: "*"
|
||||
command: "make functional-test-xdc-coverage"
|
||||
artifact_paths:
|
||||
- ".testoutput/*"
|
||||
retry:
|
||||
automatic:
|
||||
limit: 1
|
||||
plugins:
|
||||
- artifacts#v1.9.0:
|
||||
download: "develop/buildkite/*"
|
||||
- ecr#v2.7.0: {login: true}
|
||||
- docker-compose#v4.14.0:
|
||||
run: integration-test-xdc-postgresql
|
||||
config: ./develop/buildkite/docker-compose.yml
|
||||
skip-checkout: true
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional ndc test with postgresql"
|
||||
agents:
|
||||
queue: "default"
|
||||
docker: "*"
|
||||
command: "make functional-test-ndc-coverage"
|
||||
artifact_paths:
|
||||
- ".testoutput/*"
|
||||
retry:
|
||||
automatic:
|
||||
limit: 1
|
||||
plugins:
|
||||
- artifacts#v1.9.0:
|
||||
download: "develop/buildkite/*"
|
||||
- ecr#v2.7.0: {login: true}
|
||||
- docker-compose#v4.14.0:
|
||||
run: integration-test-xdc-postgresql
|
||||
config: ./develop/buildkite/docker-compose.yml
|
||||
skip-checkout: true
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional test with postgresql pgx"
|
||||
agents:
|
||||
queue: "default"
|
||||
docker: "*"
|
||||
command: "make functional-test-coverage"
|
||||
parallelism: 3
|
||||
artifact_paths:
|
||||
- ".testoutput/*"
|
||||
retry:
|
||||
automatic:
|
||||
limit: 1
|
||||
plugins:
|
||||
- artifacts#v1.9.0:
|
||||
download: "develop/buildkite/*"
|
||||
- ecr#v2.7.0: {login: true}
|
||||
- docker-compose#v4.14.0:
|
||||
run: integration-test-postgresql-pgx
|
||||
config: ./develop/buildkite/docker-compose.yml
|
||||
skip-checkout: true
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional xdc test with postgresql pgx"
|
||||
agents:
|
||||
queue: "default"
|
||||
docker: "*"
|
||||
command: "make functional-test-xdc-coverage"
|
||||
artifact_paths:
|
||||
- ".testoutput/*"
|
||||
retry:
|
||||
automatic:
|
||||
limit: 1
|
||||
plugins:
|
||||
- artifacts#v1.9.0:
|
||||
download: "develop/buildkite/*"
|
||||
- ecr#v2.7.0: {login: true}
|
||||
- docker-compose#v4.14.0:
|
||||
run: integration-test-xdc-postgresql-pgx
|
||||
config: ./develop/buildkite/docker-compose.yml
|
||||
skip-checkout: true
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional ndc test with postgresql pgx"
|
||||
agents:
|
||||
queue: "default"
|
||||
docker: "*"
|
||||
command: "make functional-test-ndc-coverage"
|
||||
artifact_paths:
|
||||
- ".testoutput/*"
|
||||
retry:
|
||||
automatic:
|
||||
limit: 1
|
||||
plugins:
|
||||
- artifacts#v1.9.0:
|
||||
download: "develop/buildkite/*"
|
||||
- ecr#v2.7.0: {login: true}
|
||||
- docker-compose#v4.14.0:
|
||||
run: integration-test-xdc-postgresql-pgx
|
||||
config: ./develop/buildkite/docker-compose.yml
|
||||
skip-checkout: true
|
||||
mount-buildkite-agent: true
|
||||
propagate-environment: true
|
||||
|
||||
- label: ":golang: functional test with postgresql 12"
|
||||
agents:
|
||||
queue: "default"
|
||||
|
||||
@@ -40,7 +40,7 @@ persistence:
|
||||
advertised-hostname: {{ default .Env.CASSANDRA_ADDRESS_TRANSLATOR_OPTIONS "" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else if eq $db "mysql" "mysql8" }}
|
||||
{{- else if eq $db "mysql8" }}
|
||||
default:
|
||||
sql:
|
||||
pluginName: "{{ $db }}"
|
||||
@@ -93,8 +93,7 @@ persistence:
|
||||
keyFile: {{ default .Env.SQL_CERT_KEY "" }}
|
||||
enableHostVerification: {{ default .Env.SQL_HOST_VERIFICATION "false" }}
|
||||
serverName: {{ default .Env.SQL_HOST_NAME "" }}
|
||||
{{- else if eq $db "postgresql" "postgres" "postgres12" "postgres12_pgx" }}
|
||||
{{- $db := replace $db "postgresql" "postgres" 1 }}
|
||||
{{- else if eq $db "postgres12" "postgres12_pgx" }}
|
||||
default:
|
||||
sql:
|
||||
pluginName: "{{ $db }}"
|
||||
|
||||
@@ -38,8 +38,6 @@ func TestSchemaDirs(t *testing.T) {
|
||||
|
||||
dirs = PathsByDir("mysql")
|
||||
requireContains(t, []string{
|
||||
"mysql/v57/temporal",
|
||||
"mysql/v57/visibility",
|
||||
"mysql/v8/temporal",
|
||||
"mysql/v8/visibility",
|
||||
}, dirs)
|
||||
@@ -48,8 +46,6 @@ func TestSchemaDirs(t *testing.T) {
|
||||
requireContains(t, []string{
|
||||
"postgresql/v12/temporal",
|
||||
"postgresql/v12/visibility",
|
||||
"postgresql/v96/temporal",
|
||||
"postgresql/v96/visibility",
|
||||
}, dirs)
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
CREATE DATABASE temporal character set utf8;
|
||||
@@ -1,339 +0,0 @@
|
||||
CREATE TABLE namespaces(
|
||||
partition_id INT NOT NULL,
|
||||
id BINARY(16) NOT NULL,
|
||||
name VARCHAR(255) UNIQUE NOT NULL,
|
||||
notification_version BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
is_global TINYINT(1) NOT NULL,
|
||||
PRIMARY KEY(partition_id, id)
|
||||
);
|
||||
|
||||
CREATE TABLE namespace_metadata (
|
||||
partition_id INT NOT NULL,
|
||||
notification_version BIGINT NOT NULL,
|
||||
PRIMARY KEY(partition_id)
|
||||
);
|
||||
|
||||
INSERT INTO namespace_metadata (partition_id, notification_version) VALUES (54321, 1);
|
||||
|
||||
CREATE TABLE shards (
|
||||
shard_id INT NOT NULL,
|
||||
--
|
||||
range_id BIGINT NOT NULL,
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id)
|
||||
);
|
||||
|
||||
CREATE TABLE executions(
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
--
|
||||
next_event_id BIGINT NOT NULL,
|
||||
last_write_version BIGINT NOT NULL,
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
state MEDIUMBLOB NOT NULL,
|
||||
state_encoding VARCHAR(16) NOT NULL,
|
||||
db_record_version BIGINT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id)
|
||||
);
|
||||
|
||||
CREATE TABLE current_executions(
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
--
|
||||
run_id BINARY(16) NOT NULL,
|
||||
create_request_id VARCHAR(255) NOT NULL,
|
||||
state INT NOT NULL,
|
||||
status INT NOT NULL,
|
||||
start_version BIGINT NOT NULL DEFAULT 0,
|
||||
last_write_version BIGINT NOT NULL,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id)
|
||||
);
|
||||
|
||||
CREATE TABLE buffered_events (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
id BIGINT AUTO_INCREMENT NOT NULL UNIQUE,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, id)
|
||||
);
|
||||
|
||||
CREATE TABLE tasks (
|
||||
range_hash INT UNSIGNED NOT NULL,
|
||||
task_queue_id VARBINARY(272) NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (range_hash, task_queue_id, task_id)
|
||||
);
|
||||
|
||||
-- Stores ephemeral task queue information such as ack levels and expiry times
|
||||
CREATE TABLE task_queues (
|
||||
range_hash INT UNSIGNED NOT NULL,
|
||||
task_queue_id VARBINARY(272) NOT NULL,
|
||||
--
|
||||
range_id BIGINT NOT NULL,
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (range_hash, task_queue_id)
|
||||
);
|
||||
|
||||
-- Stores task queue information such as user provided versioning data
|
||||
CREATE TABLE task_queue_user_data (
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
task_queue_name VARCHAR(255) NOT NULL,
|
||||
data MEDIUMBLOB NOT NULL, -- temporal.server.api.persistence.v1.TaskQueueUserData
|
||||
data_encoding VARCHAR(16) NOT NULL, -- Encoding type used for serialization, in practice this should always be proto3
|
||||
version BIGINT NOT NULL, -- Version of this row, used for optimistic concurrency
|
||||
PRIMARY KEY (namespace_id, task_queue_name)
|
||||
);
|
||||
|
||||
-- Stores a mapping between build ids and task queues
|
||||
CREATE TABLE build_id_to_task_queue (
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
build_id VARCHAR(255) NOT NULL,
|
||||
task_queue_name VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (namespace_id, build_id, task_queue_name)
|
||||
);
|
||||
|
||||
CREATE TABLE history_immediate_tasks(
|
||||
shard_id INT NOT NULL,
|
||||
category_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, category_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE history_scheduled_tasks (
|
||||
shard_id INT NOT NULL,
|
||||
category_id INT NOT NULL,
|
||||
visibility_timestamp DATETIME(6) NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, category_id, visibility_timestamp, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE transfer_tasks(
|
||||
shard_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE timer_tasks (
|
||||
shard_id INT NOT NULL,
|
||||
visibility_timestamp DATETIME(6) NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, visibility_timestamp, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE replication_tasks (
|
||||
shard_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE replication_tasks_dlq (
|
||||
source_cluster_name VARCHAR(255) NOT NULL,
|
||||
shard_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (source_cluster_name, shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE visibility_tasks(
|
||||
shard_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE activity_info_maps (
|
||||
-- each row corresponds to one key of one map<string, ActivityInfo>
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
schedule_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, schedule_id)
|
||||
);
|
||||
|
||||
CREATE TABLE timer_info_maps (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
timer_id VARCHAR(255) NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, timer_id)
|
||||
);
|
||||
|
||||
CREATE TABLE child_execution_info_maps (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE request_cancel_info_maps (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE signal_info_maps (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE signals_requested_sets (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
signal_id VARCHAR(255) NOT NULL,
|
||||
--
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, signal_id)
|
||||
);
|
||||
|
||||
-- history eventsV2: history_node stores history event data
|
||||
CREATE TABLE history_node (
|
||||
shard_id INT NOT NULL,
|
||||
tree_id BINARY(16) NOT NULL,
|
||||
branch_id BINARY(16) NOT NULL,
|
||||
node_id BIGINT NOT NULL,
|
||||
txn_id BIGINT NOT NULL,
|
||||
--
|
||||
prev_txn_id BIGINT NOT NULL DEFAULT 0,
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, tree_id, branch_id, node_id, txn_id)
|
||||
);
|
||||
|
||||
-- history eventsV2: history_tree stores branch metadata
|
||||
CREATE TABLE history_tree (
|
||||
shard_id INT NOT NULL,
|
||||
tree_id BINARY(16) NOT NULL,
|
||||
branch_id BINARY(16) NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, tree_id, branch_id)
|
||||
);
|
||||
|
||||
CREATE TABLE queue (
|
||||
queue_type INT NOT NULL,
|
||||
message_id BIGINT NOT NULL,
|
||||
message_payload MEDIUMBLOB NOT NULL,
|
||||
message_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY(queue_type, message_id)
|
||||
);
|
||||
|
||||
CREATE TABLE queue_metadata (
|
||||
queue_type INT NOT NULL,
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
version BIGINT NOT NULL,
|
||||
PRIMARY KEY(queue_type)
|
||||
);
|
||||
|
||||
CREATE TABLE cluster_metadata_info (
|
||||
metadata_partition INT NOT NULL,
|
||||
cluster_name VARCHAR(255) NOT NULL,
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
version BIGINT NOT NULL,
|
||||
PRIMARY KEY(metadata_partition, cluster_name)
|
||||
);
|
||||
|
||||
CREATE TABLE cluster_membership
|
||||
(
|
||||
membership_partition INT NOT NULL,
|
||||
host_id BINARY(16) NOT NULL,
|
||||
rpc_address VARCHAR(128) NOT NULL,
|
||||
rpc_port SMALLINT NOT NULL,
|
||||
role TINYINT NOT NULL,
|
||||
session_start TIMESTAMP DEFAULT '1970-01-02 00:00:01',
|
||||
last_heartbeat TIMESTAMP DEFAULT '1970-01-02 00:00:01',
|
||||
record_expiry TIMESTAMP DEFAULT '1970-01-02 00:00:01',
|
||||
INDEX (role, host_id),
|
||||
INDEX (role, last_heartbeat),
|
||||
INDEX (rpc_address, role),
|
||||
INDEX (last_heartbeat),
|
||||
INDEX (record_expiry),
|
||||
PRIMARY KEY (membership_partition, host_id)
|
||||
);
|
||||
|
||||
CREATE TABLE queues (
|
||||
queue_type INT NOT NULL,
|
||||
queue_name VARCHAR(255) NOT NULL,
|
||||
metadata_payload MEDIUMBLOB NOT NULL,
|
||||
metadata_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (queue_type, queue_name)
|
||||
);
|
||||
|
||||
CREATE TABLE queue_messages (
|
||||
queue_type INT NOT NULL,
|
||||
queue_name VARCHAR(255) NOT NULL,
|
||||
queue_partition BIGINT NOT NULL,
|
||||
message_id BIGINT NOT NULL,
|
||||
message_payload MEDIUMBLOB NOT NULL,
|
||||
message_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (
|
||||
queue_type,
|
||||
queue_name,
|
||||
queue_partition,
|
||||
message_id
|
||||
)
|
||||
);
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.0",
|
||||
"MinCompatibleVersion": "0.1",
|
||||
"Description": "base version of schema",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"schema.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,260 +0,0 @@
|
||||
CREATE TABLE namespaces(
|
||||
partition_id INT NOT NULL,
|
||||
id BINARY(16) NOT NULL,
|
||||
name VARCHAR(255) UNIQUE NOT NULL,
|
||||
notification_version BIGINT NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
is_global TINYINT(1) NOT NULL,
|
||||
PRIMARY KEY(partition_id, id)
|
||||
);
|
||||
|
||||
CREATE TABLE namespace_metadata (
|
||||
partition_id INT NOT NULL,
|
||||
notification_version BIGINT NOT NULL,
|
||||
PRIMARY KEY(partition_id)
|
||||
);
|
||||
|
||||
INSERT INTO namespace_metadata (partition_id, notification_version) VALUES (54321, 1);
|
||||
|
||||
CREATE TABLE shards (
|
||||
shard_id INT NOT NULL,
|
||||
--
|
||||
range_id BIGINT NOT NULL,
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id)
|
||||
);
|
||||
|
||||
CREATE TABLE transfer_tasks(
|
||||
shard_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE executions(
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
--
|
||||
next_event_id BIGINT NOT NULL,
|
||||
last_write_version BIGINT NOT NULL,
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
state BLOB NOT NULL,
|
||||
state_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id)
|
||||
);
|
||||
|
||||
CREATE TABLE current_executions(
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
--
|
||||
run_id BINARY(16) NOT NULL,
|
||||
create_request_id VARCHAR(64) NOT NULL,
|
||||
state INT NOT NULL,
|
||||
status INT NOT NULL,
|
||||
start_version BIGINT NOT NULL,
|
||||
last_write_version BIGINT NOT NULL,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id)
|
||||
);
|
||||
|
||||
CREATE TABLE buffered_events (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
id BIGINT AUTO_INCREMENT NOT NULL UNIQUE,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, id)
|
||||
);
|
||||
|
||||
CREATE TABLE tasks (
|
||||
range_hash INT UNSIGNED NOT NULL,
|
||||
task_queue_id VARBINARY(272) NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (range_hash, task_queue_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE task_queues (
|
||||
range_hash INT UNSIGNED NOT NULL,
|
||||
task_queue_id VARBINARY(272) NOT NULL,
|
||||
--
|
||||
range_id BIGINT NOT NULL,
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (range_hash, task_queue_id)
|
||||
);
|
||||
|
||||
CREATE TABLE replication_tasks (
|
||||
shard_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE replication_tasks_dlq (
|
||||
source_cluster_name VARCHAR(255) NOT NULL,
|
||||
shard_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (source_cluster_name, shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE timer_tasks (
|
||||
shard_id INT NOT NULL,
|
||||
visibility_timestamp DATETIME(6) NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, visibility_timestamp, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE activity_info_maps (
|
||||
-- each row corresponds to one key of one map<string, ActivityInfo>
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
schedule_id BIGINT NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, schedule_id)
|
||||
);
|
||||
|
||||
CREATE TABLE timer_info_maps (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
timer_id VARCHAR(255) NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, timer_id)
|
||||
);
|
||||
|
||||
CREATE TABLE child_execution_info_maps (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE request_cancel_info_maps (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE signal_info_maps (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE signals_requested_sets (
|
||||
shard_id INT NOT NULL,
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BINARY(16) NOT NULL,
|
||||
signal_id VARCHAR(64) NOT NULL,
|
||||
--
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, signal_id)
|
||||
);
|
||||
|
||||
-- history eventsV2: history_node stores history event data
|
||||
CREATE TABLE history_node (
|
||||
shard_id INT NOT NULL,
|
||||
tree_id BINARY(16) NOT NULL,
|
||||
branch_id BINARY(16) NOT NULL,
|
||||
node_id BIGINT NOT NULL,
|
||||
txn_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, tree_id, branch_id, node_id, txn_id)
|
||||
);
|
||||
|
||||
-- history eventsV2: history_tree stores branch metadata
|
||||
CREATE TABLE history_tree (
|
||||
shard_id INT NOT NULL,
|
||||
tree_id BINARY(16) NOT NULL,
|
||||
branch_id BINARY(16) NOT NULL,
|
||||
--
|
||||
data BLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, tree_id, branch_id)
|
||||
);
|
||||
|
||||
CREATE TABLE queue (
|
||||
queue_type INT NOT NULL,
|
||||
message_id BIGINT NOT NULL,
|
||||
message_payload BLOB NOT NULL,
|
||||
PRIMARY KEY(queue_type, message_id)
|
||||
);
|
||||
|
||||
CREATE TABLE queue_metadata (
|
||||
queue_type INT NOT NULL,
|
||||
data BLOB NOT NULL,
|
||||
PRIMARY KEY(queue_type)
|
||||
);
|
||||
|
||||
CREATE TABLE cluster_metadata (
|
||||
metadata_partition INT NOT NULL,
|
||||
immutable_data BLOB NOT NULL,
|
||||
immutable_data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY(metadata_partition)
|
||||
);
|
||||
|
||||
CREATE TABLE cluster_membership
|
||||
(
|
||||
membership_partition INT NOT NULL,
|
||||
host_id BINARY(16) NOT NULL,
|
||||
rpc_address VARCHAR(15) NOT NULL,
|
||||
rpc_port SMALLINT NOT NULL,
|
||||
role TINYINT NOT NULL,
|
||||
session_start TIMESTAMP DEFAULT '1970-01-02 00:00:01',
|
||||
last_heartbeat TIMESTAMP DEFAULT '1970-01-02 00:00:01',
|
||||
record_expiry TIMESTAMP DEFAULT '1970-01-02 00:00:01',
|
||||
INDEX (role, host_id),
|
||||
INDEX (role, last_heartbeat),
|
||||
INDEX (rpc_address, role),
|
||||
INDEX (last_heartbeat),
|
||||
INDEX (record_expiry),
|
||||
PRIMARY KEY (membership_partition, host_id)
|
||||
);
|
||||
@@ -1,3 +0,0 @@
|
||||
ALTER TABLE cluster_metadata ADD data BLOB NOT NULL;
|
||||
ALTER TABLE cluster_metadata ADD data_encoding VARCHAR(16) NOT NULL DEFAULT 'Proto3';
|
||||
ALTER TABLE cluster_metadata ADD version BIGINT NOT NULL DEFAULT 1;
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.1",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for cluster metadata",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"cluster_metadata.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.10",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "add storage for update records and create task_queue_user_data table",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"task_queue_user_data.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
-- Stores task queue information such as user provided versioning data
|
||||
CREATE TABLE task_queue_user_data (
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
task_queue_name VARCHAR(255) NOT NULL,
|
||||
data MEDIUMBLOB NOT NULL, -- temporal.server.api.persistence.v1.TaskQueueUserData
|
||||
data_encoding VARCHAR(16) NOT NULL, -- Encoding type used for serialization, in practice this should always be proto3
|
||||
version BIGINT NOT NULL, -- Version of this row, used for optimistic concurrency
|
||||
PRIMARY KEY (namespace_id, task_queue_name)
|
||||
);
|
||||
|
||||
-- Stores a mapping between build ids and task queues
|
||||
CREATE TABLE build_id_to_task_queue (
|
||||
namespace_id BINARY(16) NOT NULL,
|
||||
build_id VARCHAR(255) NOT NULL,
|
||||
task_queue_name VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (namespace_id, build_id, task_queue_name)
|
||||
);
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.11",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "add queues and queue_messages tables",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"queues.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
CREATE TABLE queues (
|
||||
queue_type INT NOT NULL,
|
||||
queue_name VARCHAR(255) NOT NULL,
|
||||
metadata_payload MEDIUMBLOB NOT NULL,
|
||||
metadata_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (queue_type, queue_name)
|
||||
);
|
||||
|
||||
CREATE TABLE queue_messages (
|
||||
queue_type INT NOT NULL,
|
||||
queue_name VARCHAR(255) NOT NULL,
|
||||
queue_partition BIGINT NOT NULL,
|
||||
message_id BIGINT NOT NULL,
|
||||
message_payload MEDIUMBLOB NOT NULL,
|
||||
message_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (
|
||||
queue_type,
|
||||
queue_name,
|
||||
queue_partition,
|
||||
message_id
|
||||
)
|
||||
);
|
||||
@@ -1,20 +0,0 @@
|
||||
ALTER TABLE namespaces MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE shards MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE transfer_tasks MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE executions MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE executions MODIFY COLUMN state MEDIUMBLOB;
|
||||
ALTER TABLE tasks MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE task_queues MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE replication_tasks MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE replication_tasks_dlq MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE timer_tasks MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE activity_info_maps MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE timer_info_maps MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE child_execution_info_maps MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE request_cancel_info_maps MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE signal_info_maps MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE history_tree MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE queue MODIFY COLUMN message_payload MEDIUMBLOB;
|
||||
ALTER TABLE queue_metadata MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE cluster_metadata MODIFY COLUMN data MEDIUMBLOB;
|
||||
ALTER TABLE cluster_metadata MODIFY COLUMN immutable_data MEDIUMBLOB;
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.2",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for RPC replication and blob size adjustments",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"queue.sql",
|
||||
"blob_size.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
ALTER TABLE queue ADD message_encoding VARCHAR(16) NOT NULL DEFAULT 'Json';
|
||||
ALTER TABLE queue_metadata ADD data_encoding VARCHAR(16) NOT NULL DEFAULT 'Json';
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.3",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for kafka deprecation",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"visibility_tasks.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
CREATE TABLE visibility_tasks(
|
||||
shard_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
@@ -1,2 +0,0 @@
|
||||
ALTER TABLE cluster_metadata DROP immutable_data;
|
||||
ALTER TABLE cluster_metadata DROP immutable_data_encoding;
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.4",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for cluster metadata cleanup",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"cluster_metadata.sql"
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE cluster_membership MODIFY COLUMN rpc_address VARCHAR(128);
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE history_node ADD prev_txn_id BIGINT NOT NULL DEFAULT 0;
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE executions ADD db_record_version BIGINT NOT NULL DEFAULT 0;
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.5",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for cluster_membership, executions and history_node tables",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"event.sql",
|
||||
"executions.sql",
|
||||
"cluster_membership.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.6",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for queue_metadata",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"queue_metadata.sql"
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE queue_metadata ADD version BIGINT NOT NULL DEFAULT 0;
|
||||
@@ -1,8 +0,0 @@
|
||||
CREATE TABLE cluster_metadata_info (
|
||||
metadata_partition INT NOT NULL,
|
||||
cluster_name VARCHAR(255) NOT NULL,
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
version BIGINT NOT NULL,
|
||||
PRIMARY KEY(metadata_partition, cluster_name)
|
||||
);
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.7",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "create cluster metadata info table to store cluster information and executions to store tiered storage queue",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"cluster_metadata_info.sql",
|
||||
"no_start_version.sql",
|
||||
"tiered_storage_tasks.sql"
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE current_executions ALTER COLUMN start_version SET DEFAULT 0;
|
||||
@@ -1,8 +0,0 @@
|
||||
CREATE TABLE tiered_storage_tasks (
|
||||
shard_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
@@ -1,2 +0,0 @@
|
||||
ALTER TABLE current_executions MODIFY COLUMN create_request_id VARCHAR(255);
|
||||
ALTER TABLE signals_requested_sets MODIFY COLUMN signal_id VARCHAR(255);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE tiered_storage_tasks;
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.8",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "drop unused tasks table; expand VARCHAR columns governed by maxIDLength to VARCHAR(255)",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"drop_unused_tasks_table.sql",
|
||||
"alter_columns.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
CREATE TABLE history_immediate_tasks(
|
||||
shard_id INT NOT NULL,
|
||||
category_id INT NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, category_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE history_scheduled_tasks (
|
||||
shard_id INT NOT NULL,
|
||||
category_id INT NOT NULL,
|
||||
visibility_timestamp DATETIME(6) NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data MEDIUMBLOB NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, category_id, visibility_timestamp, task_id)
|
||||
);
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.9",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "add history tasks table",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"history_tasks_table.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// The MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package v57
|
||||
|
||||
// NOTE: whenever there is a new database schema update, plz update the following versions
|
||||
|
||||
// Version is the MySQL database release version
|
||||
const Version = "1.11"
|
||||
|
||||
// VisibilityVersion is the MySQL visibility database release version
|
||||
const VisibilityVersion = "1.1"
|
||||
@@ -1 +0,0 @@
|
||||
CREATE DATABASE temporal_visibility character set utf8;
|
||||
@@ -1,24 +0,0 @@
|
||||
CREATE TABLE executions_visibility (
|
||||
namespace_id CHAR(64) NOT NULL,
|
||||
run_id CHAR(64) NOT NULL,
|
||||
start_time DATETIME(6) NOT NULL,
|
||||
execution_time DATETIME(6) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
workflow_type_name VARCHAR(255) NOT NULL,
|
||||
status INT NOT NULL, -- enum WorkflowExecutionStatus {RUNNING, COMPLETED, FAILED, CANCELED, TERMINATED, CONTINUED_AS_NEW, TIMED_OUT}
|
||||
close_time DATETIME(6) NULL,
|
||||
history_length BIGINT,
|
||||
memo BLOB,
|
||||
encoding VARCHAR(64) NOT NULL,
|
||||
task_queue VARCHAR(255) DEFAULT '' NOT NULL,
|
||||
|
||||
PRIMARY KEY (namespace_id, run_id)
|
||||
);
|
||||
|
||||
CREATE INDEX by_type_start_time ON executions_visibility (namespace_id, workflow_type_name, status, start_time DESC, run_id);
|
||||
CREATE INDEX by_workflow_id_start_time ON executions_visibility (namespace_id, workflow_id, status, start_time DESC, run_id);
|
||||
CREATE INDEX by_status_by_start_time ON executions_visibility (namespace_id, status, start_time DESC, run_id);
|
||||
CREATE INDEX by_type_close_time ON executions_visibility (namespace_id, workflow_type_name, status, close_time DESC, run_id);
|
||||
CREATE INDEX by_workflow_id_close_time ON executions_visibility (namespace_id, workflow_id, status, close_time DESC, run_id);
|
||||
CREATE INDEX by_status_by_close_time ON executions_visibility (namespace_id, status, close_time DESC, run_id);
|
||||
CREATE INDEX by_close_time_by_status ON executions_visibility (namespace_id, close_time DESC, run_id, status);
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.0",
|
||||
"MinCompatibleVersion": "0.1",
|
||||
"Description": "base version of visibility schema",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"schema.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
CREATE TABLE executions_visibility (
|
||||
namespace_id CHAR(64) NOT NULL,
|
||||
run_id CHAR(64) NOT NULL,
|
||||
start_time DATETIME(6) NOT NULL,
|
||||
execution_time DATETIME(6) NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
workflow_type_name VARCHAR(255) NOT NULL,
|
||||
status INT NOT NULL, -- enum WorkflowExecutionStatus {RUNNING, COMPLETED, FAILED, CANCELED, TERMINATED, CONTINUED_AS_NEW, TIMED_OUT}
|
||||
close_time DATETIME(6) NULL,
|
||||
history_length BIGINT,
|
||||
memo BLOB,
|
||||
encoding VARCHAR(64) NOT NULL,
|
||||
task_queue VARCHAR(255) DEFAULT '' NOT NULL,
|
||||
|
||||
PRIMARY KEY (namespace_id, run_id)
|
||||
);
|
||||
|
||||
CREATE INDEX by_type_start_time ON executions_visibility (namespace_id, workflow_type_name, status, start_time DESC, run_id);
|
||||
CREATE INDEX by_workflow_id_start_time ON executions_visibility (namespace_id, workflow_id, status, start_time DESC, run_id);
|
||||
CREATE INDEX by_status_by_start_time ON executions_visibility (namespace_id, status, start_time DESC, run_id);
|
||||
CREATE INDEX by_type_close_time ON executions_visibility (namespace_id, workflow_type_name, status, close_time DESC, run_id);
|
||||
CREATE INDEX by_workflow_id_close_time ON executions_visibility (namespace_id, workflow_id, status, close_time DESC, run_id);
|
||||
CREATE INDEX by_status_by_close_time ON executions_visibility (namespace_id, status, close_time DESC, run_id);
|
||||
@@ -1 +0,0 @@
|
||||
CREATE INDEX by_close_time_by_status ON executions_visibility (namespace_id, close_time DESC, run_id, status);
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.1",
|
||||
"MinCompatibleVersion": "0.1",
|
||||
"Description": "add close time & status index",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"index.sql"
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
CREATE DATABASE temporal;
|
||||
@@ -1,340 +0,0 @@
|
||||
CREATE TABLE namespaces(
|
||||
partition_id INTEGER NOT NULL,
|
||||
id BYTEA NOT NULL,
|
||||
name VARCHAR(255) UNIQUE NOT NULL,
|
||||
notification_version BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
is_global BOOLEAN NOT NULL,
|
||||
PRIMARY KEY(partition_id, id)
|
||||
);
|
||||
|
||||
CREATE TABLE namespace_metadata (
|
||||
partition_id INTEGER NOT NULL,
|
||||
notification_version BIGINT NOT NULL,
|
||||
PRIMARY KEY(partition_id)
|
||||
);
|
||||
|
||||
INSERT INTO namespace_metadata (partition_id, notification_version) VALUES (54321, 1);
|
||||
|
||||
CREATE TABLE shards (
|
||||
shard_id INTEGER NOT NULL,
|
||||
--
|
||||
range_id BIGINT NOT NULL,
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id)
|
||||
);
|
||||
|
||||
CREATE TABLE executions(
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
--
|
||||
next_event_id BIGINT NOT NULL,
|
||||
last_write_version BIGINT NOT NULL,
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
state BYTEA NOT NULL,
|
||||
state_encoding VARCHAR(16) NOT NULL,
|
||||
db_record_version BIGINT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id)
|
||||
);
|
||||
|
||||
CREATE TABLE current_executions(
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
--
|
||||
run_id BYTEA NOT NULL,
|
||||
create_request_id VARCHAR(255) NOT NULL,
|
||||
state INTEGER NOT NULL,
|
||||
status INTEGER NOT NULL,
|
||||
start_version BIGINT NOT NULL DEFAULT 0,
|
||||
last_write_version BIGINT NOT NULL,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id)
|
||||
);
|
||||
|
||||
CREATE TABLE buffered_events (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
id BIGSERIAL NOT NULL UNIQUE,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, id)
|
||||
);
|
||||
|
||||
CREATE TABLE tasks (
|
||||
range_hash BIGINT NOT NULL,
|
||||
task_queue_id BYTEA NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (range_hash, task_queue_id, task_id)
|
||||
);
|
||||
|
||||
-- Stores ephemeral task queue information such as ack levels and expiry times
|
||||
CREATE TABLE task_queues (
|
||||
range_hash BIGINT NOT NULL,
|
||||
task_queue_id BYTEA NOT NULL,
|
||||
--
|
||||
range_id BIGINT NOT NULL,
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (range_hash, task_queue_id)
|
||||
);
|
||||
|
||||
-- Stores task queue information such as user provided versioning data
|
||||
CREATE TABLE task_queue_user_data (
|
||||
namespace_id BYTEA NOT NULL,
|
||||
task_queue_name VARCHAR(255) NOT NULL,
|
||||
data BYTEA NOT NULL, -- temporal.server.api.persistence.v1.TaskQueueUserData
|
||||
data_encoding VARCHAR(16) NOT NULL, -- Encoding type used for serialization, in practice this should always be proto3
|
||||
version BIGINT NOT NULL, -- Version of this row, used for optimistic concurrency
|
||||
PRIMARY KEY (namespace_id, task_queue_name)
|
||||
);
|
||||
|
||||
-- Stores a mapping between build ids and task queues
|
||||
CREATE TABLE build_id_to_task_queue (
|
||||
namespace_id BYTEA NOT NULL,
|
||||
build_id VARCHAR(255) NOT NULL,
|
||||
task_queue_name VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (namespace_id, build_id, task_queue_name)
|
||||
);
|
||||
|
||||
CREATE TABLE history_immediate_tasks(
|
||||
shard_id INTEGER NOT NULL,
|
||||
category_id INTEGER NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, category_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE history_scheduled_tasks (
|
||||
shard_id INTEGER NOT NULL,
|
||||
category_id INTEGER NOT NULL,
|
||||
visibility_timestamp TIMESTAMP NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, category_id, visibility_timestamp, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE transfer_tasks(
|
||||
shard_id INTEGER NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE timer_tasks (
|
||||
shard_id INTEGER NOT NULL,
|
||||
visibility_timestamp TIMESTAMP NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, visibility_timestamp, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE replication_tasks (
|
||||
shard_id INTEGER NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE replication_tasks_dlq (
|
||||
source_cluster_name VARCHAR(255) NOT NULL,
|
||||
shard_id INTEGER NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (source_cluster_name, shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE visibility_tasks(
|
||||
shard_id INTEGER NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE activity_info_maps (
|
||||
-- each row corresponds to one key of one map<string, ActivityInfo>
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
schedule_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, schedule_id)
|
||||
);
|
||||
|
||||
CREATE TABLE timer_info_maps (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
timer_id VARCHAR(255) NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, timer_id)
|
||||
);
|
||||
|
||||
CREATE TABLE child_execution_info_maps (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE request_cancel_info_maps (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE signal_info_maps (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE signals_requested_sets (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
signal_id VARCHAR(255) NOT NULL,
|
||||
--
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, signal_id)
|
||||
);
|
||||
|
||||
-- history eventsV2: history_node stores history event data
|
||||
CREATE TABLE history_node (
|
||||
shard_id INTEGER NOT NULL,
|
||||
tree_id BYTEA NOT NULL,
|
||||
branch_id BYTEA NOT NULL,
|
||||
node_id BIGINT NOT NULL,
|
||||
txn_id BIGINT NOT NULL,
|
||||
--
|
||||
prev_txn_id BIGINT NOT NULL DEFAULT 0,
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, tree_id, branch_id, node_id, txn_id)
|
||||
);
|
||||
|
||||
-- history eventsV2: history_tree stores branch metadata
|
||||
CREATE TABLE history_tree (
|
||||
shard_id INTEGER NOT NULL,
|
||||
tree_id BYTEA NOT NULL,
|
||||
branch_id BYTEA NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, tree_id, branch_id)
|
||||
);
|
||||
|
||||
CREATE TABLE queue (
|
||||
queue_type INTEGER NOT NULL,
|
||||
message_id BIGINT NOT NULL,
|
||||
message_payload BYTEA NOT NULL,
|
||||
message_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY(queue_type, message_id)
|
||||
);
|
||||
|
||||
CREATE TABLE queue_metadata (
|
||||
queue_type INTEGER NOT NULL,
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
version BIGINT NOT NULL,
|
||||
PRIMARY KEY(queue_type)
|
||||
);
|
||||
|
||||
CREATE TABLE cluster_metadata_info (
|
||||
metadata_partition INTEGER NOT NULL,
|
||||
cluster_name VARCHAR(255) NOT NULL,
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
version BIGINT NOT NULL,
|
||||
PRIMARY KEY(metadata_partition, cluster_name)
|
||||
);
|
||||
|
||||
CREATE TABLE cluster_membership
|
||||
(
|
||||
membership_partition INTEGER NOT NULL,
|
||||
host_id BYTEA NOT NULL,
|
||||
rpc_address VARCHAR(128) NOT NULL,
|
||||
rpc_port SMALLINT NOT NULL,
|
||||
role SMALLINT NOT NULL,
|
||||
session_start TIMESTAMP DEFAULT '1970-01-01 00:00:01+00:00',
|
||||
last_heartbeat TIMESTAMP DEFAULT '1970-01-01 00:00:01+00:00',
|
||||
record_expiry TIMESTAMP DEFAULT '1970-01-01 00:00:01+00:00',
|
||||
PRIMARY KEY (membership_partition, host_id)
|
||||
);
|
||||
|
||||
CREATE TABLE queues (
|
||||
queue_type INT NOT NULL,
|
||||
queue_name VARCHAR(255) NOT NULL,
|
||||
metadata_payload BYTEA NOT NULL,
|
||||
metadata_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (queue_type, queue_name)
|
||||
);
|
||||
|
||||
CREATE TABLE queue_messages (
|
||||
queue_type INT NOT NULL,
|
||||
queue_name VARCHAR(255) NOT NULL,
|
||||
queue_partition BIGINT NOT NULL,
|
||||
message_id BIGINT NOT NULL,
|
||||
message_payload BYTEA NOT NULL,
|
||||
message_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (
|
||||
queue_type,
|
||||
queue_name,
|
||||
queue_partition,
|
||||
message_id
|
||||
)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX cm_idx_rolehost ON cluster_membership (role, host_id);
|
||||
CREATE INDEX cm_idx_rolelasthb ON cluster_membership (role, last_heartbeat);
|
||||
CREATE INDEX cm_idx_rpchost ON cluster_membership (rpc_address, role);
|
||||
CREATE INDEX cm_idx_lasthb ON cluster_membership (last_heartbeat);
|
||||
CREATE INDEX cm_idx_recordexpiry ON cluster_membership (record_expiry);
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.0",
|
||||
"MinCompatibleVersion": "0.1",
|
||||
"Description": "base version of schema",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"schema.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
CREATE TABLE namespaces(
|
||||
partition_id INTEGER NOT NULL,
|
||||
id BYTEA NOT NULL,
|
||||
name VARCHAR(255) UNIQUE NOT NULL,
|
||||
notification_version BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
is_global BOOLEAN NOT NULL,
|
||||
PRIMARY KEY(partition_id, id)
|
||||
);
|
||||
|
||||
CREATE TABLE namespace_metadata (
|
||||
partition_id INTEGER NOT NULL,
|
||||
notification_version BIGINT NOT NULL,
|
||||
PRIMARY KEY(partition_id)
|
||||
);
|
||||
|
||||
INSERT INTO namespace_metadata (partition_id, notification_version) VALUES (54321, 1);
|
||||
|
||||
CREATE TABLE shards (
|
||||
shard_id INTEGER NOT NULL,
|
||||
--
|
||||
range_id BIGINT NOT NULL,
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id)
|
||||
);
|
||||
|
||||
CREATE TABLE transfer_tasks(
|
||||
shard_id INTEGER NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE executions(
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
--
|
||||
next_event_id BIGINT NOT NULL,
|
||||
last_write_version BIGINT NOT NULL,
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
state BYTEA NOT NULL,
|
||||
state_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id)
|
||||
);
|
||||
|
||||
CREATE TABLE current_executions(
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
--
|
||||
run_id BYTEA NOT NULL,
|
||||
create_request_id VARCHAR(64) NOT NULL,
|
||||
state INTEGER NOT NULL,
|
||||
status INTEGER NOT NULL,
|
||||
start_version BIGINT NOT NULL,
|
||||
last_write_version BIGINT NOT NULL,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id)
|
||||
);
|
||||
|
||||
CREATE TABLE buffered_events (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
id BIGSERIAL NOT NULL UNIQUE,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, id)
|
||||
);
|
||||
|
||||
CREATE TABLE tasks (
|
||||
range_hash BIGINT NOT NULL,
|
||||
task_queue_id BYTEA NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (range_hash, task_queue_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE task_queues (
|
||||
range_hash BIGINT NOT NULL,
|
||||
task_queue_id BYTEA NOT NULL,
|
||||
--
|
||||
range_id BIGINT NOT NULL,
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (range_hash, task_queue_id)
|
||||
);
|
||||
|
||||
CREATE TABLE replication_tasks (
|
||||
shard_id INTEGER NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE replication_tasks_dlq (
|
||||
source_cluster_name VARCHAR(255) NOT NULL,
|
||||
shard_id INTEGER NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (source_cluster_name, shard_id, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE timer_tasks (
|
||||
shard_id INTEGER NOT NULL,
|
||||
visibility_timestamp TIMESTAMP NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, visibility_timestamp, task_id)
|
||||
);
|
||||
|
||||
CREATE TABLE activity_info_maps (
|
||||
-- each row corresponds to one key of one map<string, ActivityInfo>
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
schedule_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, schedule_id)
|
||||
);
|
||||
|
||||
CREATE TABLE timer_info_maps (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
timer_id VARCHAR(255) NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, timer_id)
|
||||
);
|
||||
|
||||
CREATE TABLE child_execution_info_maps (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE request_cancel_info_maps (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE signal_info_maps (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
initiated_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16),
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, initiated_id)
|
||||
);
|
||||
|
||||
CREATE TABLE signals_requested_sets (
|
||||
shard_id INTEGER NOT NULL,
|
||||
namespace_id BYTEA NOT NULL,
|
||||
workflow_id VARCHAR(255) NOT NULL,
|
||||
run_id BYTEA NOT NULL,
|
||||
signal_id VARCHAR(64) NOT NULL,
|
||||
--
|
||||
PRIMARY KEY (shard_id, namespace_id, workflow_id, run_id, signal_id)
|
||||
);
|
||||
|
||||
-- history eventsV2: history_node stores history event data
|
||||
CREATE TABLE history_node (
|
||||
shard_id INTEGER NOT NULL,
|
||||
tree_id BYTEA NOT NULL,
|
||||
branch_id BYTEA NOT NULL,
|
||||
node_id BIGINT NOT NULL,
|
||||
txn_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, tree_id, branch_id, node_id, txn_id)
|
||||
);
|
||||
|
||||
-- history eventsV2: history_tree stores branch metadata
|
||||
CREATE TABLE history_tree (
|
||||
shard_id INTEGER NOT NULL,
|
||||
tree_id BYTEA NOT NULL,
|
||||
branch_id BYTEA NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, tree_id, branch_id)
|
||||
);
|
||||
|
||||
CREATE TABLE queue (
|
||||
queue_type INTEGER NOT NULL,
|
||||
message_id BIGINT NOT NULL,
|
||||
message_payload BYTEA NOT NULL,
|
||||
PRIMARY KEY(queue_type, message_id)
|
||||
);
|
||||
|
||||
CREATE TABLE queue_metadata (
|
||||
queue_type INTEGER NOT NULL,
|
||||
data BYTEA NOT NULL,
|
||||
PRIMARY KEY(queue_type)
|
||||
);
|
||||
|
||||
CREATE TABLE cluster_metadata (
|
||||
metadata_partition INTEGER NOT NULL,
|
||||
immutable_data BYTEA NOT NULL,
|
||||
immutable_data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY(metadata_partition)
|
||||
);
|
||||
|
||||
CREATE TABLE cluster_membership
|
||||
(
|
||||
membership_partition INTEGER NOT NULL,
|
||||
host_id BYTEA NOT NULL,
|
||||
rpc_address VARCHAR(15) NOT NULL,
|
||||
rpc_port SMALLINT NOT NULL,
|
||||
role SMALLINT NOT NULL,
|
||||
session_start TIMESTAMP DEFAULT '1970-01-01 00:00:01+00:00',
|
||||
last_heartbeat TIMESTAMP DEFAULT '1970-01-01 00:00:01+00:00',
|
||||
record_expiry TIMESTAMP DEFAULT '1970-01-01 00:00:01+00:00',
|
||||
PRIMARY KEY (membership_partition, host_id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX cm_idx_rolehost ON cluster_membership (role, host_id);
|
||||
CREATE INDEX cm_idx_rolelasthb ON cluster_membership (role, last_heartbeat);
|
||||
CREATE INDEX cm_idx_rpchost ON cluster_membership (rpc_address, role);
|
||||
CREATE INDEX cm_idx_lasthb ON cluster_membership (last_heartbeat);
|
||||
CREATE INDEX cm_idx_recordexpiry ON cluster_membership (record_expiry);
|
||||
@@ -1,3 +0,0 @@
|
||||
ALTER TABLE cluster_metadata ADD data BYTEA NOT NULL DEFAULT '';
|
||||
ALTER TABLE cluster_metadata ADD data_encoding VARCHAR(16) NOT NULL DEFAULT 'Proto3';
|
||||
ALTER TABLE cluster_metadata ADD version BIGINT NOT NULL DEFAULT 1;
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.1",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for cluster metadata",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"cluster_metadata.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.10",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "add storage for update records and create task_queue_user_data table",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"task_queue_user_data.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
-- Stores task queue information such as user provided versioning data
|
||||
CREATE TABLE task_queue_user_data (
|
||||
namespace_id BYTEA NOT NULL,
|
||||
task_queue_name VARCHAR(255) NOT NULL,
|
||||
data BYTEA NOT NULL, -- temporal.server.api.persistence.v1.TaskQueueUserData
|
||||
data_encoding VARCHAR(16) NOT NULL, -- Encoding type used for serialization, in practice this should always be proto3
|
||||
version BIGINT NOT NULL, -- Version of this row, used for optimistic concurrency
|
||||
PRIMARY KEY (namespace_id, task_queue_name)
|
||||
);
|
||||
|
||||
-- Stores a mapping between build ids and task queues
|
||||
CREATE TABLE build_id_to_task_queue (
|
||||
namespace_id BYTEA NOT NULL,
|
||||
build_id VARCHAR(255) NOT NULL,
|
||||
task_queue_name VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (namespace_id, build_id, task_queue_name)
|
||||
);
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.11",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "add queues and queue_messages tables",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"queue_v2.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
CREATE TABLE queues (
|
||||
queue_type INT NOT NULL,
|
||||
queue_name VARCHAR(255) NOT NULL,
|
||||
metadata_payload BYTEA NOT NULL,
|
||||
metadata_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (queue_type, queue_name)
|
||||
);
|
||||
|
||||
CREATE TABLE queue_messages (
|
||||
queue_type INT NOT NULL,
|
||||
queue_name VARCHAR(255) NOT NULL,
|
||||
queue_partition BIGINT NOT NULL,
|
||||
message_id BIGINT NOT NULL,
|
||||
message_payload BYTEA NOT NULL,
|
||||
message_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (
|
||||
queue_type,
|
||||
queue_name,
|
||||
queue_partition,
|
||||
message_id
|
||||
)
|
||||
);
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.2",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for RPC replication",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"queue.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
ALTER TABLE queue ADD message_encoding VARCHAR(16) NOT NULL DEFAULT 'Json';
|
||||
ALTER TABLE queue_metadata ADD data_encoding VARCHAR(16) NOT NULL DEFAULT 'Json';
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.3",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for kafka deprecation",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"visibility_tasks.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
CREATE TABLE visibility_tasks(
|
||||
shard_id INTEGER NOT NULL,
|
||||
task_id BIGINT NOT NULL,
|
||||
--
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
PRIMARY KEY (shard_id, task_id)
|
||||
);
|
||||
@@ -1,2 +0,0 @@
|
||||
ALTER TABLE cluster_metadata DROP immutable_data;
|
||||
ALTER TABLE cluster_metadata DROP immutable_data_encoding;
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.4",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for cluster metadata cleanup",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"cluster_metadata.sql"
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE cluster_membership ALTER COLUMN rpc_address TYPE VARCHAR(128);
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE history_node ADD prev_txn_id BIGINT NOT NULL DEFAULT 0;
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE executions ADD db_record_version BIGINT NOT NULL DEFAULT 0;
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.5",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for cluster_membership, executions and history_node tables",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"event.sql",
|
||||
"executions.sql",
|
||||
"cluster_membership.sql"
|
||||
]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"CurrVersion": "1.6",
|
||||
"MinCompatibleVersion": "1.0",
|
||||
"Description": "schema update for queue_metadata",
|
||||
"SchemaUpdateCqlFiles": [
|
||||
"queue_metadata.sql"
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE queue_metadata ADD version BIGINT NOT NULL DEFAULT 0;
|
||||
@@ -1,8 +0,0 @@
|
||||
CREATE TABLE cluster_metadata_info (
|
||||
metadata_partition INTEGER NOT NULL,
|
||||
cluster_name VARCHAR(255) NOT NULL,
|
||||
data BYTEA NOT NULL,
|
||||
data_encoding VARCHAR(16) NOT NULL,
|
||||
version BIGINT NOT NULL,
|
||||
PRIMARY KEY(metadata_partition, cluster_name)
|
||||
);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user