deco

package
v0.0.0-...-91c5940 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2017 License: GPL-3.0 Imports: 11 Imported by: 0

Documentation

Overview

Package deco contains the decorator of RSQL.

It walks the AST tree:
    - it creates the dataslot for each Token_primary. See walk_Token_primary_and_simplify().
    - it inserts promotion Token_primary (CAST token) for operator or function arguments, so that they have the proper datatype
    - it inserts promotion Token_primary (CAST token) for assignment, to make expression exactly the same datatype and attributes as variable
    - simplification for CAST(CAST ...) ...) is done. E.g. CAST(CAST(10.123 as INT) as INT) is simplified into CAST(10.123 as INT)
    - constant folding is done

IMPORTANT THING TO UNDERSTAND:
    - During decoration, lots of CAST tokens are usually inserted into the AST tree. Simplification may remove CAST tokens from the AST tree.
    - During constant folding, the AST tree structure is absolutely static. Tokens are just transformed.
    - Optimization is kept simple, to be made quickly. That's why there is no Common Subexpression Elimination (CSE). Besides, CSE would complicate the query optimizer too much.
    - In the AST tree, when the VM will execute the SQL batch and fill the dataslots in the AST, all dataslots (except KIND_VAR_LEAF and KIND_COL_LEAF) are assigned a value once (they are immutable).
    - The KIND_VAR_LEAF dataslots (in TOK_PRIM_VAR_NAMED tokens), represent variable, and their values are changed at each SET assignment (they are not immutable).
    - The KIND_COL_LEAF dataslots are columns from table. They change at each cursor Next() call.
    - The result dataslot never points to the same dataslot as an argument of an operator or function. This makes easier to write the package "data" which implements operators and functions.

Index

Constants

View Source
const (
	SPEC_DEFAULT_DICTIONARY_VARIABLE_CAPACITY = 10 // initial capacity 10 is good enough
	SPEC_DEFAULT_DICTIONARY_CONSTANT_CAPACITY = 50 // initial capacity 50 is good enough

	SPEC_FLASH_TBLID_START = -100 // first tblid for flash tables
)
View Source
const (
	S_CAST_MODE_NEUTRAL rounding_mode_t = 0 // must be 0
	S_CAST_MODE_ROUND   rounding_mode_t = 1
	S_CAST_MODE_TRUNC   rounding_mode_t = 2
)
View Source
const GROUPTABLE_NAME = "$grouptable$"
View Source
const HIGHEST_TSEQNO_UNKNOWN int = 1000000000 // any big value is good
View Source
const SORTTABLE_NAME = "$sorttable$"

Variables

View Source
var G_SQL_DATATYPE_CAST_INSTRUCTION_CODE = [rsql.DATATYPE_ARRAYSIZE][rsql.DATATYPE_ARRAYSIZE]rsql.Instrcode_t{

	rsql.DATATYPE_VOID: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_VOID_VOID,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_VOID_SYSLANGUAGE,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_VOID_VARBINARY,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_VOID_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_VOID_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_VOID_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_VOID_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_VOID_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_VOID_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_VOID_MONEY,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_VOID_NUMERIC,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_VOID_FLOAT,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_VOID_DATE,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_VOID_TIME,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_VOID_DATETIME,
	},

	rsql.DATATYPE_SYSLANGUAGE: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_SYSLANGUAGE_SYSLANGUAGE,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_ILLEGAL,
	},

	rsql.DATATYPE_BOOLEAN: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_ILLEGAL,
	},

	rsql.DATATYPE_VARBINARY: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_VARBINARY_VARBINARY,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_VARBINARY_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_VARBINARY_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_VARBINARY_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_VARBINARY_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_VARBINARY_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_ILLEGAL,
	},

	rsql.DATATYPE_IMAGE: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_ILLEGAL,
	},

	rsql.DATATYPE_VARCHAR: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_VARCHAR_SYSLANGUAGE,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_VARCHAR_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_VARCHAR_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_VARCHAR_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_VARCHAR_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_VARCHAR_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_VARCHAR_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_VARCHAR_MONEY,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_VARCHAR_NUMERIC,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_VARCHAR_FLOAT,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_VARCHAR_DATE,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_VARCHAR_TIME,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_VARCHAR_DATETIME,
	},

	rsql.DATATYPE_TEXT: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_ILLEGAL,
	},

	rsql.DATATYPE_REGEXPLIKE: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_ILLEGAL,
	},

	rsql.DATATYPE_BIT: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_BIT_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_BIT_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_BIT_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_BIT_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_BIT_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_BIT_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_BIT_MONEY,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_BIT_NUMERIC,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_BIT_FLOAT,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_ILLEGAL,
	},

	rsql.DATATYPE_TINYINT: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_TINYINT_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_TINYINT_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_TINYINT_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_TINYINT_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_TINYINT_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_TINYINT_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_TINYINT_MONEY,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_TINYINT_NUMERIC,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_TINYINT_FLOAT,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_TINYINT_DATETIME,
	},

	rsql.DATATYPE_SMALLINT: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_SMALLINT_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_SMALLINT_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_SMALLINT_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_SMALLINT_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_SMALLINT_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_SMALLINT_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_SMALLINT_MONEY,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_SMALLINT_NUMERIC,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_SMALLINT_FLOAT,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_SMALLINT_DATETIME,
	},

	rsql.DATATYPE_INT: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_INT_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_INT_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_INT_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_INT_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_INT_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_INT_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_INT_MONEY,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_INT_NUMERIC,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_INT_FLOAT,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_INT_DATETIME,
	},

	rsql.DATATYPE_BIGINT: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_BIGINT_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_BIGINT_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_BIGINT_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_BIGINT_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_BIGINT_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_BIGINT_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_BIGINT_MONEY,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_BIGINT_NUMERIC,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_BIGINT_FLOAT,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_BIGINT_DATETIME,
	},

	rsql.DATATYPE_MONEY: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_MONEY_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_MONEY_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_MONEY_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_MONEY_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_MONEY_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_MONEY_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_MONEY_MONEY,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_MONEY_NUMERIC,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_MONEY_FLOAT,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_ILLEGAL,
	},

	rsql.DATATYPE_NUMERIC: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_NUMERIC_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_NUMERIC_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_NUMERIC_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_NUMERIC_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_NUMERIC_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_NUMERIC_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_NUMERIC_MONEY,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_NUMERIC_NUMERIC,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_NUMERIC_FLOAT,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_ILLEGAL,
	},

	rsql.DATATYPE_FLOAT: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_FLOAT_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_FLOAT_BIT,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_FLOAT_TINYINT,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_FLOAT_SMALLINT,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_FLOAT_INT,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_FLOAT_BIGINT,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_FLOAT_MONEY,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_FLOAT_NUMERIC,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_FLOAT_FLOAT,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_ILLEGAL,
	},

	rsql.DATATYPE_DATE: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_DATE_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_DATE_DATE,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_DATE_DATETIME,
	},

	rsql.DATATYPE_TIME: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_TIME_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_TIME_TIME,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_TIME_DATETIME,
	},

	rsql.DATATYPE_DATETIME: {
		rsql.DATATYPE_VOID:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SYSLANGUAGE: rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BOOLEAN:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARBINARY:   rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_IMAGE:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_VARCHAR:     rsql.INSTR_CAST_DATETIME_VARCHAR,
		rsql.DATATYPE_TEXT:        rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_REGEXPLIKE:  rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_TINYINT:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_SMALLINT:    rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_INT:         rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_BIGINT:      rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_MONEY:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_NUMERIC:     rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_FLOAT:       rsql.INSTR_CAST_ILLEGAL,
		rsql.DATATYPE_DATE:        rsql.INSTR_CAST_DATETIME_DATE,
		rsql.DATATYPE_TIME:        rsql.INSTR_CAST_DATETIME_TIME,
		rsql.DATATYPE_DATETIME:    rsql.INSTR_CAST_DATETIME_DATETIME,
	},
}

G_SQL_DATATYPE_CAST_INSTRUCTION_CODE is the CAST instruction table.

IMPLICIT CASTS are of two types :
   - EQUALIZATION CAST :
      - when an operator needs its operands to be of the same datatype, we often need to cast an operand to a higher rank datatype, to match the datatype of the other operand.
      - when we need to cast arguments of a function to the datatype ( which can be higher or lower rank ) of the function parameters.
      - we just care about the datatype, and ABSOLUTELY NOT about its properties ( precision, scale, fixlen_flag ).
   - ASSIGNMENT CAST :
      - when we need to cast rvalue to variable or column, e.g. SET @a = 123, or SET mycol = 123 in an UPDATE statement.
      - the cast is done to a target which has the same datatype, but also EXACTLY THE SAME PROPERTIES ( precision, scale, fixlen_flag ) as the assignee.

EXPLICIT CASTS : corresponds to the instructions CAST(expression AS datatype), or CONVERT(datatype, expression) without any STYLE given.
If a style is given, the CAST instruction is transformed into a CONVERT(datatype, expression, style) instruction, which is a very ordinary builtin function for parsing or formatting.

The following casts are always illegal :
   - any datatype to NULL ( rsql.DATATYPE_VOID ), as we cannot declare any variable of this type, nor is it the type of any operator arguments or function parameters.
   - any datatype to rsql.DATATYPE_BOOLEAN. For instance, IF or CASE takes a boolean argument and we don't want expression such as 'IF 10' or 'CASE WHEN MYCOL THEN 'aaa' END'.
   - rsql.DATATYPE_BOOLEAN to any datatype. We don't want to allow expressions like '(2=3) + 10'.

The cast of a datatype to same datatype, e.g. INT to INT, are allowed but the token will be discarded by the decorator from the AST as it is just a plain copy operation.

Some other same-datatype casts are real operation, such as NUMERIC to NUMERIC, or VARCHAR to VARCHAR, for instance, because precision, scale, fixlen_flag may be different.
This can only occur with assignment casts or explicit casts, not with equalization casts.
But if all these properties are the same, the token should be deleted from the ast as it is a no-operation.

Functions

func Compare_tok_trees

func Compare_tok_trees(tok_a *ast.Token_primary, tok_b *ast.Token_primary) bool

func Is_CAST_COPY

func Is_CAST_COPY(instrcode rsql.Instrcode_t) bool

is_CAST_COPY returns true if instrcode is a CAST which only makes a copy of the dataslot value. This operation can be discarded by the decorator.

func MMAX16

func MMAX16(a uint16, b uint16) uint16

func New_coldef_from_dataslot

func New_coldef_from_dataslot(colname string, base_seqno int, collation string, dataslot rsql.IDataslot) *rsql.Coldef

func Sarg_list_is_empty

func Sarg_list_is_empty(list []*ast.Sarginfo) bool

func Select_ORDER_BY_is_naturally_ordered

func Select_ORDER_BY_is_naturally_ordered(columns_orderby []rsql.IDataslot, natural_order []rsql.IDataslot) bool

Types

type Condkey

type Condkey struct {
	Cond_xtable ast.Xtable // Conditions may be applied to real table, and in the future also to SELECT or UNION table (not done yet)
	Cond_seqno  int        // a sequential numbering of all conditions encountered in ON and WHERE clause
}

type Decorator

type Decorator struct {
	ast.Parser

	VARIABLES Dictionary_VARIABLE
	CONSTANTS Dictionary_CONSTANT

	Basicblock_first   *rsql.Basicblock // main entry point
	Basicblock_current *rsql.Basicblock // current basicblock during decoration stage and emit stage
	Basicblock_list    []*rsql.Basicblock

	Debug_disable_constant_folding_flag bool // should be false. You can set it to true only for debugging.
}

func New_decorator

func New_decorator(session_login_name string, session_login_id int64, language_string string, database_name string, options ast.Options_t, registration *lk.Registration) (*Decorator, *rsql.Error)

func (*Decorator) Initialize

func (decor *Decorator) Initialize(session_login_name string, session_login_id int64, language_string string, database_name string, options ast.Options_t, registration *lk.Registration) *rsql.Error

func (*Decorator) Set_disable_constant_folding_flag

func (decor *Decorator) Set_disable_constant_folding_flag(flag bool)

Set_disable_constant_folding_flag can disable constant folding. USE IT ONLY FOR DEBUGGING PURPOSE.

func (*Decorator) Token_primary_CAST_COPY_new_with_Dataslot_NOT_USED_ANY_MORE

func (decor *Decorator) Token_primary_CAST_COPY_new_with_Dataslot_NOT_USED_ANY_MORE(tok_from *ast.Token_primary) *ast.Token_primary

Token_primary_CAST_COPY_new_with_Dataslot inserts a copy token. It is used when decorating SELECT statements.

Same as Token_primary_VARIABLE_CAST_COPY_new_with_Dataslot, but collation is not changed.

NOT USED ANY MORE

func (*Decorator) Token_primary_CAST_EXACT_new_to_target_dataslot

func (decor *Decorator) Token_primary_CAST_EXACT_new_to_target_dataslot(tok_from *ast.Token_primary, target_dataslot rsql.IDataslot) (*ast.Token_primary, *rsql.Error)

Token_primary_CAST_EXACT_new_to_target_dataslot creates a CAST Token_primary to cast tok_from to target_dataslot.

It is NEVER a plain copy, e.g. INSTR_CAST_INT_INT. In this case, no conversion is needed and tok_from is returned.

The dataslot of the CAST Token_primary will be set to target_dataslot. This function is used when we need to cast a dataslot to another target dataslot. This is used by INSERT, to cast columns from a SELECT into the proper datatypes of the target table.

No simplification is done.

func (*Decorator) Token_primary_COPY_or_CAST_EXACT_new_to_target_dataslot

func (decor *Decorator) Token_primary_COPY_or_CAST_EXACT_new_to_target_dataslot(tok_from *ast.Token_primary, target_dataslot rsql.IDataslot) (*ast.Token_primary, *rsql.Error)

Token_primary_COPY_or_CAST_EXACT_new_to_target_dataslot creates a CAST Token_primary, which can be a plain copy, e.g. INSTR_CAST_INT_INT, to cast tok_from to target_dataslot. The dataslot of the CAST Token_primary will be set to target_dataslot. This function is used when we need to cast or copy a dataslot to another target dataslot. This is used for UNION, when we want to cast or copy SELECT or UNION columns to the equalized_row dataslots.

This function is exactly the same as Token_primary_CAST_EXACT_new_to_target_dataslot, but it can return a plain copy, e.g. INSTR_CAST_INT_INT.

No simplification is done.

func (*Decorator) Token_primary_FITTING_new_to_target_dataslot_for_INSERT

func (decor *Decorator) Token_primary_FITTING_new_to_target_dataslot_for_INSERT(tok_from *ast.Token_primary, target_dataslot rsql.IDataslot) (*ast.Token_primary, *rsql.Error)

Token_primary_FITTING_new_to_target_dataslot_for_INSERT creates a CAST Token_primary to convert columns of SELECT into column datatypes of INSERT INTO, with precision that fits with target precision.

For VARBINARY and VARCHAR, precision of the returned token CAN BE SMALLER than precision of target column !

If source and target dataslots are both VARBINARY, a verification token INSTR_SYSFUNC_FIT_NO_TRUNCATE_VARBINARY is returned, to check VARBINARY length before insertion in table. If source and target dataslots are both VARCHAR, a verification token INSTR_SYSFUNC_FIT_NO_TRUNCATE_VARCHAR is returned, to check VARCHAR length before insertion in table.

func (*Decorator) Token_primary_IMPLICIT_CAST_EQUALIZE_new_with_Dataslot

func (decor *Decorator) Token_primary_IMPLICIT_CAST_EQUALIZE_new_with_Dataslot(tok_from *ast.Token_primary, datatype_to rsql.Datatype_t) (tok_cast *ast.Token_primary, rsql_err *rsql.Error)

Token_primary_IMPLICIT_CAST_EQUALIZE_new_with_Dataslot is used for "implicit equalizing cast".

This kind of operation takes place with most operators, when one operand must be cast to the 'stronger' datatype of the other operand. But with other operation like ISNULL(a,b), the operand b must be cast to the datatype of a, which can be 'weaker' ( that is, of lesser rank ).

declare @a int
declare @b float
select @a + @b         -- the '+' operator result type is float. @a is implicitly cast from INT to FLOAT

select ISNULL(@a, @b)  -- @b is implicitly cast from FLOAT to INT

If the two operands are not of the same datatype, a new CAST Token_primary is created and inserted in the AST between the '+' operator and the operand to convert 'tok_from'.

This function is called during the walking of the ast, and all operands have already been processed and have their datatypes defined.

The target datatype 'datatype_to' MUST BE DIFFERENT than datatype of 'tok_from'. Else, panics. The caller must check this.

Returns pointer to the new CAST Token_primary

The important point is that the function should create a CAST token using only the 'datatype_to' argument.
This function doesn't need other info like p, s, collation, etc.

*** WE JUST GIVE THE PLAIN TARGET DATATYPE (without p, s, or whatever) AND THIS FUNCTION SHOULD CREATE THE PROPER CAST TOKEN ***

*** WE JUST WANT TO HAVE THE SAME DATATYPE FOR BOTH OPERANDS, BUT WE DON'T CARE ABOUT THE PRECISION, SCALE, OR FIXLEN_FLAG ***
         - an operator can have an operand which is a normal VARCHAR(p) and the other being a VARCHAR(q) with fixlen_flag==true, for instance.
         - an operator can have an operand of type NUMERIC(p,s) and the other of type NUMERIC(q,r)

We don't care about p, s, or fixlen_flag of the target. We see indeed that this information is not passed in the list of function arguments.

For the moment, only VOID can be implicitly cast to VARCHAR.

func (*Decorator) Token_primary_IMPLICIT_CAST_EQUALIZE_new_with_Dataslot_no_simplify

func (decor *Decorator) Token_primary_IMPLICIT_CAST_EQUALIZE_new_with_Dataslot_no_simplify(tok_from *ast.Token_primary, datatype_to rsql.Datatype_t) (tok_cast *ast.Token_primary, rsql_err *rsql.Error)

Token_primary_IMPLICIT_CAST_EQUALIZE_new_with_Dataslot_no_simplify creates a CAST Token for implicit equalization. See comments for Token_primary_IMPLICIT_CAST_EQUALIZE_new_with_Dataslot.

The target datatype 'datatype_to' MUST BE DIFFERENT than datatype of 'tok_from'. Else, panics. The caller must check this.

A new CAST Token is always returned, because no simplification is done.

This function is used by wacf_Xtable_union() in walk_statements_SELECT.go.

func (*Decorator) Token_primary_IMPLICIT_CAST_EXACT_new_with_Dataslot

func (decor *Decorator) Token_primary_IMPLICIT_CAST_EXACT_new_with_Dataslot(tok_from *ast.Token_primary, sample_Data_XXX_to rsql.IDataslot) (*ast.Token_primary, *rsql.Error)

Token_primary_IMPLICIT_CAST_EXACT_new_with_Dataslot creates a CAST token, used to implicitly cast a dataslot to exactly the same datatype and attributes as sample dataslot passed as argument.

This kind of operation takes place when a value is assigned to a variable, or to a column in an INSERT statement, or to a user function argument.

declare @a int
set @a = 123.45    -- NUMERIC(5,2) --> INT

If rvalue and lvalue are not EXACTLY of the same datatype, a new CAST Token_primary is created and inserted in the AST between the '=' assignment operator and the operand 'tok_from' to convert.

This function is called during the walking of the ast, and all operands have already been processed and have their datatypes defined.

***IMPORTANT*** For variable assignment, the caller must force collation to be the collation of the variable, which is always default server collation.
                When a variable occurence will later point to this Token_primary, it will copy this collation, which is what we want.

********* WE WANT DATAYPE, BUT ALSO PRECISION, SCALE, AND FIXLEN_FLAG TO MATCH THOSE OF THE TARGET *********
          (FOR VARIABLE ASSIGNMENT, IF VARCHAR DATASLOT, THE CALLER MUST FORCE COLLATION_STRENGTH AND COLLATION TO DEFAULT SERVER COLLATION, WHICH IS THE COLLATION FOR ALL VARCHAR VARIABLES)

func (*Decorator) Token_primary_SYSFUNC_FIT_NO_TRUNCATE_VARBINARY_new_with_Dataslot

func (decor *Decorator) Token_primary_SYSFUNC_FIT_NO_TRUNCATE_VARBINARY_new_with_Dataslot(tok_from *ast.Token_primary, precision_to uint16) *ast.Token_primary

Token_primary_SYSFUNC_FIT_NO_TRUNCATE_VARBINARY_new_with_Dataslot inserts a verification token INSTR_SYSFUNC_FIT_NO_TRUNCATE_VARBINARY, to check VARBINARY length before insertion in table. Argument tok_from must be *VARBINARY.

It is a function, not a CAST, but as its purpose is much like a CAST, it is defined here.

If no verification token is needed because target precision is larger than source, tok_from is returned.

func (*Decorator) Token_primary_SYSFUNC_FIT_NO_TRUNCATE_VARCHAR_new_with_Dataslot

func (decor *Decorator) Token_primary_SYSFUNC_FIT_NO_TRUNCATE_VARCHAR_new_with_Dataslot(tok_from *ast.Token_primary, precision_to uint16, fixlen_flag_to bool) *ast.Token_primary

Token_primary_SYSFUNC_FIT_NO_TRUNCATE_VARCHAR_new_with_Dataslot inserts a verification token INSTR_SYSFUNC_FIT_NO_TRUNCATE_VARCHAR, to check VARCHAR length before insertion in table. Argument tok_from must be *VARCHAR.

It is a function, not a CAST, but as its purpose is much like a CAST, it is defined here.

If no verification token is needed because target precision is larger than source, tok_from is returned.

func (*Decorator) Token_primary_VARIABLE_CAST_COPY_new_with_Dataslot_NOT_USED_ANY_MORE

func (decor *Decorator) Token_primary_VARIABLE_CAST_COPY_new_with_Dataslot_NOT_USED_ANY_MORE(tok_from *ast.Token_primary) *ast.Token_primary

Token_primary_VARIABLE_CAST_COPY_new_with_Dataslot was used to insert a copy of @b in SET @a = @b

Works well, but NOT USED ANY MORE.

func (*Decorator) Wacf_all_AST

func (decor *Decorator) Wacf_all_AST(tok ast.Tokener) *rsql.Error

Wacf_all_AST decorates the entire ast tree.

walk-constfold all tokens, starting from tok.

func (*Decorator) Wacf_expression

func (decor *Decorator) Wacf_expression(tok_expression *ast.Token_primary) *rsql.Error

Wacf_expression is the main function that will walk/constfold an expression. Use it each time a statement token needs to process an expression.

If you want the expression to be a requested datatype, you can use the function Wacf_expression_with_promotion instead.

func (*Decorator) Wacf_expression_FITTING_for_INSERT_column

func (decor *Decorator) Wacf_expression_FITTING_for_INSERT_column(tok_expression *ast.Token_primary, sample_Data_XXX_to rsql.IDataslot) (*ast.Token_primary, *rsql.Error)

Wacf_expression_FITTING_for_INSERT_column is like Wacf_expression_with_promotion, but used only for expression to INSERT INTO table.

For VARBINARY and VARCHAR, precision of the returned token CAN BE SMALLER than precision of target column !

A promotion token is inserted if needed using Token_primary_IMPLICIT_CAST_EXACT_new_with_Dataslot(), and will be returned. If expression and table column are VARBINARY, Token_primary_SYSFUNC_FIT_NO_TRUNCATE_VARBINARY_new_with_Dataslot() is used instead. If expression and table column are VARCHAR, Token_primary_SYSFUNC_FIT_NO_TRUNCATE_VARCHAR_new_with_Dataslot() is used instead.

func (*Decorator) Wacf_expression_with_promotion

func (decor *Decorator) Wacf_expression_with_promotion(tok_expression *ast.Token_primary, requested_datatype rsql.Datatype_t) (*ast.Token_primary, *rsql.Error)

Wacf_expression_with_promotion is the main function that will walk/constfold an expression. Use it each time a statement token needs to process an expression.

A promotion token is inserted if needed using Token_primary_IMPLICIT_CAST_EQUALIZE_new_with_Dataslot(), and will be returned.

func (*Decorator) Wacf_expression_with_promotion_exact_for_variable_assignment

func (decor *Decorator) Wacf_expression_with_promotion_exact_for_variable_assignment(tok_expression *ast.Token_primary, sample_Data_XXX_to rsql.IDataslot) (*ast.Token_primary, *rsql.Error)

Wacf_expression_with_promotion_exact_for_variable_assignment is like Wacf_expression_with_promotion, but target datatype is more precise. It is used for right-hand expression of variable assignment.

A promotion token is inserted if needed using Token_primary_IMPLICIT_CAST_EXACT_new_with_Dataslot(), and will be returned.

********* WE WANT DATAYPE, BUT ALSO PRECISION, SCALE, AND FIXLEN_FLAG TO MATCH THOSE OF THE SAMPLE DATASLOT *********
          (FOR VARCHAR DATASLOT, COLLATION_STRENGTH AND COLLATION ARE FORCED TO DEFAULT SERVER COLLATION, WHICH IS THE COLLATION FOR ALL VARCHAR VARIABLES)

type Dictionary_CONSTANT

type Dictionary_CONSTANT struct {
	Tbl map[uint32][]rsql.IDataslot
}

Dictionary_CONSTANT contains all constants dataslots in a SQL batch, with no duplicate. Table_CONSTANT is indeed a set of constant values. These dataslots must be KIND_RO_LEAF.

func (*Dictionary_CONSTANT) Const_walk_Token_primary

func (dc *Dictionary_CONSTANT) Const_walk_Token_primary(tok *ast.Token_primary)

Const_walk_Token_primary walks the AST. If a Token_primary has a constant dataslot, it is put in a table of constants.

If the constant dataslot already exists in the table, it is reused.

func (*Dictionary_CONSTANT) Get_RO_LEAF_Data_XXX

func (dc *Dictionary_CONSTANT) Get_RO_LEAF_Data_XXX(dataslot rsql.IDataslot) (res rsql.IDataslot, hashval uint32)

Get_RO_LEAF_Data_XXX returns a pointer to a KIND_RO_LEAF Data_XXX. It can point to the same dataslot as the argument passed, or to a dataslot with same value if it already exists in the constant table.

func (*Dictionary_CONSTANT) Initialize

func (dc *Dictionary_CONSTANT) Initialize()

type Dictionary_VARIABLE

type Dictionary_VARIABLE struct {
	Tbl map[string]rsql.IDataslot
}

Dictionary_VARIABLE is a map containing all the global variables of the batch.

func (*Dictionary_VARIABLE) Get_current_db_name

func (dictvar *Dictionary_VARIABLE) Get_current_db_name() string

func (*Dictionary_VARIABLE) Get_symbol_entry

func (dictvar *Dictionary_VARIABLE) Get_symbol_entry(varname string) (rsql.IDataslot, *rsql.Error)

func (*Dictionary_VARIABLE) Initialize

func (dictvar *Dictionary_VARIABLE) Initialize(session_login_name string, session_login_id int64, language_string string, database_name string) *rsql.Error

func (*Dictionary_VARIABLE) Put

func (dictvar *Dictionary_VARIABLE) Put(varname string, dataslot rsql.IDataslot) *rsql.Error

func (*Dictionary_VARIABLE) Put_system_variables

func (dictvar *Dictionary_VARIABLE) Put_system_variables(session_login_name string, session_login_id int64, language_string string, database_name string) *rsql.Error

Put_system_variables creates system variables.

All arguments must be in lowercase.

func (*Dictionary_VARIABLE) Update_current_timestamp

func (dictvar *Dictionary_VARIABLE) Update_current_timestamp()

type Gf_entry_t

type Gf_entry_t struct {
	// contains filtered or unexported fields
}

type Group_splitup

type Group_splitup struct {
	// contains filtered or unexported fields
}

func (*Group_splitup) Process_GROUPING_SELECT

func (gs *Group_splitup) Process_GROUPING_SELECT(xtable_select *ast.Xtable_select, grouptable_gtblid int64) (grouptable_xtable_from *ast.Xtable_from, rsql_err *rsql.Error)

Process_GROUPING_SELECT is the main function to process a grouping SELECT.

It creates the grouptable, default insertion row, break up SELECT expressions into parts to inject into grouptable row, and parts that read grouptable, etc. The processing result is put in Group_splitup receiver.

type Index_score

type Index_score struct {
	Sc_xtable           *ast.Xtable_table
	Sc_base_table_qname rsql.Object_qname_t
	Sc_base_table_alias string
	Sc_indexname        string
	Sc_indexdef         *rsql.Tabledef
	Sc_sortkind         Sc_sortkind_t // used for sorting the scores from best to worse. SC_SORTKIND_CLUSTERED_KEY, _NONCLUSTERED_PRIMARY_KEY, _NONCLUSTERED_UNIQUE, _NONCLUSTERED_INDEX

	Sc_sarginfos_equal []*ast.Sarginfo // size is length(indexdef.Td_nk). Contains '=' Sarginfos for leading nk fields.
	Sc_sarginfos_low   []*ast.Sarginfo // size is length(indexdef.Td_nk). Contains '>' and '>=' Sarginfos for leading nk fields.
	Sc_sarginfos_high  []*ast.Sarginfo // size is 1. Contains '<' and '<=' Sarginfo for first nk fields.

	Sc_lookup_type csr.Sc_lookup_type_t // if Sc_sarginfos_equal[0] contains a Sarginfo, it is SC_LOOKUP_EQUALITY. Else, if Sc_sarginfos_low[0] or Sc_sarginfos_high[0] contains a Sarginfo, SC_LOOKUP_RANGE. Else, index is not usable.

	Sc_nk_leading_colcount int // if Sc_lookup_type is SC_LOOKUP_EQUALITY, count of leading Sarginfos in Sc_sarginfos_equal. Else, count of leading Sarginfos in Sc_sarginfos_low (can be 0).
	Sc_nk_total_colcount   int // len(indexdef.Td_nk)

	Sc_significant_nk_leading_colcount int // same as Sc_nk_leading_colcount, at least 1. But for SC_SORTKIND_NONCLUSTERED_INDEX, if no Sarginfo for rowid, Sc_nk_leading_colcount-1
	Sc_significant_nk_total_colcount   int // same as above

	Sc_significant_weight     int // Sc_significant_nk_leading_colcount value, scaled relative to Sc_significant_weight_max
	Sc_significant_weight_max int // a common multiple of Sc_significant_nk_total_colcount value for all Index_scores

	Sc_condinfos []*ast.Condinfo // other conditions that can be applied to the table
}

Index_score contains for each index the information about its usability. Index_score for all indexes will be compared to find the more efficient.

The algorithm is as follows:

Sort the list of scores as follows and take the first:

       1) by Sc_lookup_type                        SC_LOOKUP_EQUALITY, SC_LOOKUP_RANGE
       2) by Sc_significant_weight (desc):         the portion of index that is used for search
       3) by Sc_sortkind:                          SC_SORTKIND_CLUSTERED_KEY, _NONCLUSTERED_PRIMARY_KEY, _NONCLUSTERED_UNIQUE, _NONCLUSTERED_INDEX
       4) by Sc_significant_nk_leading_colcount
       5) by Sc_indexname                          as tiebreaker

If list of scores is empty, no index is usable.

func (*Index_score) String

func (score *Index_score) String() string

type List_of_condinfos

type List_of_condinfos []*ast.Condinfo

func (List_of_condinfos) Len

func (list List_of_condinfos) Len() int

func (List_of_condinfos) Less

func (list List_of_condinfos) Less(i, j int) bool

func (List_of_condinfos) Swap

func (list List_of_condinfos) Swap(i, j int)

type List_of_scores

type List_of_scores []*Index_score

func (List_of_scores) Len

func (list List_of_scores) Len() int

func (List_of_scores) Less

func (list List_of_scores) Less(i, j int) bool

The sort is done in the following order:

  1. by Sc_lookup_type SC_LOOKUP_EQUALITY, SC_LOOKUP_RANGE
  2. by Sc_significant_weight (desc): the portion of index that is used for search
  3. by Sc_sortkind: SC_SORTKIND_CLUSTERED_KEY, _NONCLUSTERED_PRIMARY_KEY, _NONCLUSTERED_UNIQUE, _NONCLUSTERED_INDEX
  4. by Sc_significant_nk_leading_colcount
  5. by Sc_indexname as tiebreaker

func (List_of_scores) Swap

func (list List_of_scores) Swap(i, j int)

type List_of_scores_2

type List_of_scores_2 []*Index_score

func (List_of_scores_2) Len

func (list List_of_scores_2) Len() int

func (List_of_scores_2) Less

func (list List_of_scores_2) Less(i, j int) bool

Sort scores in descending Sc_significant_nk_total_colcount order. This is done to have a small common multiple. This is done also for aesthetical reason because the common multiple value may have different value if order of scores in list is different (because the order of this list is random).

func (List_of_scores_2) Swap

func (list List_of_scores_2) Swap(i, j int)

type Optimizer

type Optimizer struct {
	Map_xtbl           map[ast.Xtable]*Xtbl_entry // filled-in when walking the JOIN tree, with real table, SELECT or UNION tables.
	Last_table_in_from map[*ast.Xtable_from]ast.Xtable
	// contains filtered or unexported fields
}

func New_optimizer

func New_optimizer() *Optimizer

func (*Optimizer) Optimize_all

func (opz *Optimizer) Optimize_all(xtable ast.Xtable) *rsql.Error

Optimize_all analyzes and optimizes all real tables in the tree of tables passed as argument.

type Orderby_attr

type Orderby_attr struct {
	Col_no          int
	Force_collation string // collation of the ORDER BY item, but only if COLLSTRENGTH_2. Else, empty string.
}

type Sargkey

type Sargkey struct {
	Sarg_xtable         *ast.Xtable_table
	Sarg_col_base_seqno uint16
	Sarg_comp           csr.Sarg_comp_t
}

NOTE: if a Sarg is entered in opz.current_sarginfos map and a Sarg for the same table, column and comparison operator already exists in the map, the latter is replaced by the new one.

type Sc_sortkind_t

type Sc_sortkind_t uint8
const (
	SC_SORTKIND_CLUSTERED_KEY Sc_sortkind_t = iota + 1
	SC_SORTKIND_NONCLUSTERED_PRIMARY_KEY
	SC_SORTKIND_NONCLUSTERED_UNIQUE
	SC_SORTKIND_NONCLUSTERED_INDEX
)

the value of these constants are used for sort purpose. Don't change their order !

func (Sc_sortkind_t) String

func (sk Sc_sortkind_t) String() string

type Xe_sortable

type Xe_sortable []*Xtbl_entry

func (Xe_sortable) Len

func (a Xe_sortable) Len() int

func (Xe_sortable) Less

func (a Xe_sortable) Less(i, j int) bool

func (Xe_sortable) Swap

func (a Xe_sortable) Swap(i, j int)

type Xtbl_entry

type Xtbl_entry struct {
	// contains filtered or unexported fields
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL