From 5d7b982c10a1efa6b9feebe3ab94afde80271f1e Mon Sep 17 00:00:00 2001 From: Kushaal Shroff <51415286+KushaalShroff@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:30:39 +0530 Subject: [PATCH] PG-Vector support in Babelfish (#2232) With GenAI capturing the imagination and Vector Similarity search being one of the foundational features in this space, we MUST leverage what is being offered by pgvector and make it available for T-SQL applications. With this commit, users can install the vector extension in SYS schema and start using not only the datatype but also all of the other features available in pgvector extension [https://github.com/pgvector/pgvector]. NOTE: Except for Creation of IVFFLAT and HNSW indexes, rest all queries must follow TSQL syntax and semantics. TASK: BABEL-4687 Signed-off-by: Kushaal Shroff kushaal@amazon.com --- .../build-vector-extension/action.yml | 22 + .../setup-base-version/action.yml | 12 + .../setup-new-version/action.yml | 9 +- .github/workflows/code-coverage.yml | 7 +- ...ests-with-non-default-server-collation.yml | 7 +- .../jdbc-tests-with-parallel-query.yml | 7 +- .github/workflows/jdbc-tests.yml | 7 +- .github/workflows/major-version-upgrade.yml | 9 +- .github/workflows/minor-version-upgrade.yml | 12 + contrib/babelfishpg_common/src/typecode.c | 1 + contrib/babelfishpg_common/src/typecode.h | 2 +- .../babelfishpg_tds--1.0.0.sql | 2 +- .../src/backend/tds/tds_data_map.c | 5 +- contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 | 8 + contrib/babelfishpg_tsql/antlr/TSqlParser.g4 | 26 +- .../babelfishpg_tsql/sql/babelfishpg_tsql.sql | 1 + .../sql/information_schema_tsql.sql | 2 +- contrib/babelfishpg_tsql/sql/sys_views.sql | 1 + .../babelfishpg_tsql--3.4.0--3.5.0.sql | 5 +- .../src/backend_parser/gram-tsql-epilogue.y.c | 4 +- contrib/babelfishpg_tsql/src/datatype_info.h | 15 +- contrib/babelfishpg_tsql/src/pl_handler.c | 4 + contrib/babelfishpg_tsql/src/procedures.c | 48 +- contrib/babelfishpg_tsql/src/tsqlIface.cpp | 34 +- test/JDBC/expected/TestVectorDatatype.out | 1491 ++++++++++++++++ test/JDBC/expected/babel_typecode.out | 1 + .../chinese_prc_ci_as/TestVectorDatatype.out | 1491 ++++++++++++++++ .../parallel_query/TestVectorDatatype.out | 1566 +++++++++++++++++ .../input/datatypes/TestVectorDatatype.mix | 567 ++++++ 29 files changed, 5345 insertions(+), 21 deletions(-) create mode 100644 .github/composite-actions/build-vector-extension/action.yml create mode 100644 test/JDBC/expected/TestVectorDatatype.out create mode 100644 test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestVectorDatatype.out create mode 100644 test/JDBC/expected/parallel_query/TestVectorDatatype.out create mode 100644 test/JDBC/input/datatypes/TestVectorDatatype.mix diff --git a/.github/composite-actions/build-vector-extension/action.yml b/.github/composite-actions/build-vector-extension/action.yml new file mode 100644 index 0000000000..d992361966 --- /dev/null +++ b/.github/composite-actions/build-vector-extension/action.yml @@ -0,0 +1,22 @@ +name: 'Build vector Extension' + +inputs: + install_dir: + description: 'Engine install directory' + required: no + default: psql + +runs: + using: "composite" + steps: + - name: Build vector Extension + run: | + cd .. + export VECTOR_VERSION="0.5.1" + sudo apt-get install wget + wget https://github.com/pgvector/pgvector/archive/refs/tags/v${VECTOR_VERSION}.tar.gz + tar -xvzf v${VECTOR_VERSION}.tar.gz + cd pgvector-${VECTOR_VERSION}/ + make USE_PGXS=1 PG_CONFIG=~/${{ inputs.install_dir }}/bin/pg_config + sudo make USE_PGXS=1 PG_CONFIG=~/${{ inputs.install_dir }}/bin/pg_config install + shell: bash diff --git a/.github/composite-actions/setup-base-version/action.yml b/.github/composite-actions/setup-base-version/action.yml index 8416b8f2f1..9f4c6956dc 100644 --- a/.github/composite-actions/setup-base-version/action.yml +++ b/.github/composite-actions/setup-base-version/action.yml @@ -63,6 +63,18 @@ runs: sudo make USE_PGXS=1 PG_CONFIG=~/${{ inputs.install_dir }}/bin/pg_config install shell: bash + - name: Build vector Extension + run: | + cd .. + export VECTOR_VERSION="0.5.1" + sudo apt-get install wget + wget https://github.com/pgvector/pgvector/archive/refs/tags/v${VECTOR_VERSION}.tar.gz + tar -xvzf v${VECTOR_VERSION}.tar.gz + cd pgvector-${VECTOR_VERSION}/ + make USE_PGXS=1 PG_CONFIG=~/${{ inputs.install_dir }}/bin/pg_config + sudo make USE_PGXS=1 PG_CONFIG=~/${{ inputs.install_dir }}/bin/pg_config install + shell: bash + - name: Build PostGIS Extension run: | cd .. diff --git a/.github/composite-actions/setup-new-version/action.yml b/.github/composite-actions/setup-new-version/action.yml index fec5646bd8..2b1378f4cc 100644 --- a/.github/composite-actions/setup-new-version/action.yml +++ b/.github/composite-actions/setup-new-version/action.yml @@ -44,9 +44,16 @@ runs: with: install_dir: ${{ inputs.pg_new_dir }} + - name: Build vector Extension + id: build-vector-extension + if: always() && steps.build-tds_fdw-extension.outcome == 'success' + uses: ./.github/composite-actions/build-vector-extension + with: + install_dir: ${{ inputs.pg_new_dir }} + - name: Build PostGIS Extension id: build-postgis-extension - if: always() && steps.build-tds_fdw-extension.outcome == 'success' + if: always() && steps.build-vector-extension.outcome == 'success' uses: ./.github/composite-actions/build-postgis-extension with: install_dir: ${{ inputs.pg_new_dir }} diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml index 74380efec6..c4a01c05a6 100644 --- a/.github/workflows/code-coverage.yml +++ b/.github/workflows/code-coverage.yml @@ -44,9 +44,14 @@ jobs: if: always() && steps.build-extensions.outcome == 'success' uses: ./.github/composite-actions/build-tds_fdw-extension + - name: Build vector Extension + id: build-vector-extension + if: always() && steps.build-tds_fdw-extension.outcome == 'success' + uses: ./.github/composite-actions/build-vector-extension + - name: Build PostGIS Extension id: build-postgis-extension - if: always() && steps.build-tds_fdw-extension.outcome == 'success' + if: always() && steps.build-vector-extension.outcome == 'success' uses: ./.github/composite-actions/build-postgis-extension - name: Install Extensions diff --git a/.github/workflows/jdbc-tests-with-non-default-server-collation.yml b/.github/workflows/jdbc-tests-with-non-default-server-collation.yml index 4d0d53146c..c0fc64faf5 100644 --- a/.github/workflows/jdbc-tests-with-non-default-server-collation.yml +++ b/.github/workflows/jdbc-tests-with-non-default-server-collation.yml @@ -37,9 +37,14 @@ jobs: if: always() && steps.build-extensions.outcome == 'success' uses: ./.github/composite-actions/build-tds_fdw-extension + - name: Build vector Extension + id: build-vector-extension + if: always() && steps.build-tds_fdw-extension.outcome == 'success' + uses: ./.github/composite-actions/build-vector-extension + - name: Build PostGIS Extension id: build-postgis-extension - if: always() && steps.build-tds_fdw-extension.outcome == 'success' + if: always() && steps.build-vector-extension.outcome == 'success' uses: ./.github/composite-actions/build-postgis-extension - name: Install Extensions diff --git a/.github/workflows/jdbc-tests-with-parallel-query.yml b/.github/workflows/jdbc-tests-with-parallel-query.yml index 67ed18fb75..641fffbbf6 100644 --- a/.github/workflows/jdbc-tests-with-parallel-query.yml +++ b/.github/workflows/jdbc-tests-with-parallel-query.yml @@ -35,9 +35,14 @@ jobs: if: always() && steps.build-extensions.outcome == 'success' uses: ./.github/composite-actions/build-tds_fdw-extension + - name: Build vector Extension + id: build-vector-extension + if: always() && steps.build-tds_fdw-extension.outcome == 'success' + uses: ./.github/composite-actions/build-vector-extension + - name: Build PostGIS Extension id: build-postgis-extension - if: always() && steps.build-tds_fdw-extension.outcome == 'success' + if: always() && steps.build-vector-extension.outcome == 'success' uses: ./.github/composite-actions/build-postgis-extension - name: Install Extensions diff --git a/.github/workflows/jdbc-tests.yml b/.github/workflows/jdbc-tests.yml index 24a3652890..d7aa9398e2 100644 --- a/.github/workflows/jdbc-tests.yml +++ b/.github/workflows/jdbc-tests.yml @@ -38,9 +38,14 @@ jobs: if: always() && steps.build-extensions.outcome == 'success' uses: ./.github/composite-actions/build-tds_fdw-extension + - name: Build vector Extension + id: build-vector-extension + if: always() && steps.build-tds_fdw-extension.outcome == 'success' + uses: ./.github/composite-actions/build-vector-extension + - name: Build PostGIS Extension id: build-postgis-extension - if: always() && steps.build-tds_fdw-extension.outcome == 'success' + if: always() && steps.build-vector-extension.outcome == 'success' uses: ./.github/composite-actions/build-postgis-extension - name: Install Extensions diff --git a/.github/workflows/major-version-upgrade.yml b/.github/workflows/major-version-upgrade.yml index 603544c196..4815cd4356 100644 --- a/.github/workflows/major-version-upgrade.yml +++ b/.github/workflows/major-version-upgrade.yml @@ -154,9 +154,16 @@ jobs: with: install_dir: ${{env.NEW_INSTALL_DIR}} + - name: Build vector Extension + id: build-vector-extension + if: always() && steps.build-tds_fdw-extension.outcome == 'success' + uses: ./.github/composite-actions/build-vector-extension + with: + install_dir: ${{env.NEW_INSTALL_DIR}} + - name: Build PostGIS Extension id: build-postgis-extension - if: always() && steps.build-tds_fdw-extension.outcome == 'success' + if: always() && steps.build-vector-extension.outcome == 'success' uses: ./.github/composite-actions/build-postgis-extension with: install_dir: ${{env.NEW_INSTALL_DIR}} diff --git a/.github/workflows/minor-version-upgrade.yml b/.github/workflows/minor-version-upgrade.yml index 76a034b33d..445063949b 100644 --- a/.github/workflows/minor-version-upgrade.yml +++ b/.github/workflows/minor-version-upgrade.yml @@ -92,6 +92,18 @@ jobs: sudo make USE_PGXS=1 PG_CONFIG=~/psql/bin/pg_config install shell: bash + - name: Build vector Extension + run: | + cd .. + export VECTOR_VERSION="0.5.1" + sudo apt-get install wget + wget https://github.com/pgvector/pgvector/archive/refs/tags/v${VECTOR_VERSION}.tar.gz + tar -xvzf v${VECTOR_VERSION}.tar.gz + cd pgvector-${VECTOR_VERSION}/ + make USE_PGXS=1 PG_CONFIG=~/psql/bin/pg_config + sudo make USE_PGXS=1 PG_CONFIG=~/psql/bin/pg_config install + shell: bash + - name: Install extensions id: install-extensions-older if: always() && steps.build-tds_fdw-extension.outcome == 'success' diff --git a/contrib/babelfishpg_common/src/typecode.c b/contrib/babelfishpg_common/src/typecode.c index 08f65b6969..0da995ec5a 100644 --- a/contrib/babelfishpg_common/src/typecode.c +++ b/contrib/babelfishpg_common/src/typecode.c @@ -52,6 +52,7 @@ type_info_t type_infos[TOTAL_TYPECODE_COUNT] = {0, 1, "sysname", "sysname", 5, 31, 5}, {0, 1, "rowversion", "timestamp", 8, 32, 3}, {0, 1, "timestamp", "timestamp", 8, 33, 3}, + {0, 1, "vector", "vector", 9, 34, 3}, /* * Geospatial types cannot be stored in SQL variant so setting sqlvariant header size to 1 */ diff --git a/contrib/babelfishpg_common/src/typecode.h b/contrib/babelfishpg_common/src/typecode.h index 8a9fac77c4..71ccb9bbad 100644 --- a/contrib/babelfishpg_common/src/typecode.h +++ b/contrib/babelfishpg_common/src/typecode.h @@ -45,7 +45,7 @@ #define FIXEDDECIMAL_MULTIPLIER 10000LL #endif -#define TOTAL_TYPECODE_COUNT 35 +#define TOTAL_TYPECODE_COUNT 36 struct Node; diff --git a/contrib/babelfishpg_tds/babelfishpg_tds--1.0.0.sql b/contrib/babelfishpg_tds/babelfishpg_tds--1.0.0.sql index 4c0b9938d9..575b0c3bae 100644 --- a/contrib/babelfishpg_tds/babelfishpg_tds--1.0.0.sql +++ b/contrib/babelfishpg_tds/babelfishpg_tds--1.0.0.sql @@ -47,4 +47,4 @@ LANGUAGE SQL; CREATE FUNCTION sys.disable_injected_fault_all() RETURNS text AS $$ SELECT sys.inject_fault('all', 0) $$ -LANGUAGE SQL; +LANGUAGE SQL; \ No newline at end of file diff --git a/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c b/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c index d5d9891345..95470b9666 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tds_data_map.c @@ -188,6 +188,7 @@ TdsIoFunctionRawData TdsIoFunctionRawData_data[] = /* Mapping TDS listener sender to basic Postgres datatypes. */ {"pg_catalog", "oid", TDS_TYPE_INTEGER, 4, 1, TDS_SEND_INTEGER, TDS_RECV_INVALID}, {"pg_catalog", "sql_identifier", TDS_TYPE_VARCHAR, -1, 1, TDS_SEND_VARCHAR, TDS_RECV_INVALID}, + {"sys", "vector", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_VARCHAR}, {"pg_catalog", "name", TDS_TYPE_VARCHAR, -1, 1, TDS_SEND_VARCHAR, TDS_RECV_INVALID}, {"pg_catalog", "character_data", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_INVALID}, {"pg_catalog", "bool", TDS_TYPE_BIT, 1, 1, TDS_SEND_BIT, TDS_RECV_INVALID}, @@ -221,7 +222,9 @@ TdsIoFunctionRawData TdsIoFunctionRawData_data[] = {"pg_catalog", "tid", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_INVALID}, {"pg_catalog", "inet", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_INVALID}, {"pg_catalog", "interval", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_INVALID}, - {"pg_catalog", "bytea", TDS_TYPE_VARBINARY, -1, 2, TDS_SEND_VARBINARY, TDS_RECV_INVALID} + {"pg_catalog", "bytea", TDS_TYPE_VARBINARY, -1, 2, TDS_SEND_VARBINARY, TDS_RECV_INVALID}, + {"pg_catalog", "record", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_INVALID}, + {"pg_catalog", "_record", TDS_TYPE_VARCHAR, -1, 2, TDS_SEND_VARCHAR, TDS_RECV_INVALID} }; size_t TdsIoFunctionRawData_datasize = lengthof(TdsIoFunctionRawData_data); diff --git a/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 b/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 index 59f02ee49c..f3fe695a64 100644 --- a/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 +++ b/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 @@ -441,6 +441,7 @@ HIGH: H I G H; HINT: H I N T; HISTORY_RETENTION_PERIOD: H I S T O R Y UNDERLINE R E T E N T I O N UNDERLINE P E R I O D; HISTORY_TABLE: H I S T O R Y UNDERLINE T A B L E; +HNSW: H N S W; HOLDLOCK: H O L D L O C K; HONOR_BROKER_PRIORITY: H O N O R UNDERLINE B R O K E R UNDERLINE P R I O R I T Y; HOUR: H O U R; @@ -484,6 +485,7 @@ IS: I S; ISDESCENDANTOF: I S D E S C E N D A N T O F; ISNULL: I S N U L L; ISOLATION: I S O L A T I O N; +IVFFLAT: I V F F L A T; JOB: J O B; JOIN: J O I N; JSON: J S O N; @@ -1070,6 +1072,9 @@ VAR: V A R; VARBINARY_KEYWORD: V A R B I N A R Y; VARP: V A R P; VARYING: V A R Y I N G; +VECTOR_COSINE_OPS: V E C T O R UNDERLINE C O S I N E UNDERLINE O P S; +VECTOR_IP_OPS: V E C T O R UNDERLINE I P UNDERLINE O P S; +VECTOR_L2_OPS: V E C T O R UNDERLINE L '2' UNDERLINE O P S; VERBOSELOGGING: V E R B O S E L O G G I N G; VERSION: V E R S I O N; VIEW: V I E W; @@ -1173,6 +1178,9 @@ MOD_ASSIGN: '%='; AND_ASSIGN: '&='; XOR_ASSIGN: '^='; OR_ASSIGN: '|='; +VECTOR_L2: '<->'; +VECTOR_COSINE: '<=>'; +VECTOR_IP: '<#>'; DOT: '.'; UNDERLINE: '_'; diff --git a/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 b/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 index f0c83983d6..5e7c71f6b0 100644 --- a/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 +++ b/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 @@ -1822,9 +1822,21 @@ create_index (WHERE where=search_condition)? with_index_options? (ON storage_partition_clause)? + SEMI? + |CREATE UNIQUE? clustered? COLUMNSTORE? INDEX id ON table_name (USING vector_index_method)? (LR_BRACKET column_name_list_with_order_for_vector RR_BRACKET)? + (INCLUDE LR_BRACKET column_name_list RR_BRACKET )? + (WHERE where=search_condition)? + with_index_options? + (ON storage_partition_clause)? SEMI? ; +/* We introduce specific index methods so as to avoid PG syntax leaks. */ +vector_index_method + : HNSW + | IVFFLAT + ; + alter_index : ALTER INDEX (id | ALL) ON table_name alter_index_options SEMI? @@ -3574,8 +3586,9 @@ xml_common_directives : COMMA (BINARY_KEYWORD BASE64 | TYPE | ROOT ( LR_BRACKET char_string RR_BRACKET )?) ; -order_by_expression +order_by_expression : order_by=expression (ascending=ASC | descending=DESC)? + | order_by=expression vector_operator expression (ascending=ASC | descending=DESC)? ; group_by_item @@ -5187,6 +5200,11 @@ column_name_list_with_order : simple_column_name (ASC | DESC)? (COMMA simple_column_name (ASC | DESC)?)* ; +/* We introduce specific index methods so as to avoid PG syntax leaks. */ +column_name_list_with_order_for_vector + : simple_column_name (ASC | DESC)? (VECTOR_COSINE_OPS | VECTOR_IP_OPS | VECTOR_L2_OPS)? (COMMA simple_column_name (ASC | DESC)? (VECTOR_COSINE_OPS | VECTOR_IP_OPS | VECTOR_L2_OPS)?)* + ; + //For some reason, sql server allows any number of prefixes: Here, h is the column: a.b.c.d.e.f.g.h insert_column_name_list : col+=insert_column_id (COMMA col+=insert_column_id)* @@ -5227,7 +5245,11 @@ local_id // https://msdn.microsoft.com/en-us/library/ms188074.aspx // Spaces are allowed for comparison operators. comparison_operator - : EQUAL | GREATER | LESS | LESS EQUAL | GREATER EQUAL | LESS GREATER | EXCLAMATION EQUAL | EXCLAMATION GREATER | EXCLAMATION LESS | MULT_ASSIGN | EQUAL_STAR_OJ + : EQUAL | GREATER | LESS | LESS EQUAL | GREATER EQUAL | LESS GREATER | EXCLAMATION EQUAL | EXCLAMATION GREATER | EXCLAMATION LESS | MULT_ASSIGN | EQUAL_STAR_OJ | vector_operator + ; + +vector_operator + : VECTOR_COSINE | VECTOR_IP | VECTOR_L2 ; assignment_operator diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index d340575c24..053fbc7abf 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -639,6 +639,7 @@ BEGIN WHEN 'sql_variant' THEN tds_id = 98; WHEN 'datetimeoffset' THEN tds_id = 43; WHEN 'timestamp' THEN tds_id = 173; + WHEN 'vector' THEN tds_id = 167; -- Same as varchar WHEN 'geometry' THEN tds_id = 240; WHEN 'geography' THEN tds_id = 240; ELSE tds_id = 0; diff --git a/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql b/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql index 904b19a354..668b5ae53a 100644 --- a/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql @@ -57,7 +57,7 @@ $$SELECT THEN 1073741823 WHEN type = 'sysname' THEN 128 - WHEN type IN ('xml', 'geometry', 'geography') + WHEN type IN ('xml', 'vector', 'geometry', 'geography') THEN -1 WHEN type = 'sql_variant' THEN 0 diff --git a/contrib/babelfishpg_tsql/sql/sys_views.sql b/contrib/babelfishpg_tsql/sql/sys_views.sql index a89f21fff9..f33c717ab7 100644 --- a/contrib/babelfishpg_tsql/sql/sys_views.sql +++ b/contrib/babelfishpg_tsql/sql/sys_views.sql @@ -353,6 +353,7 @@ BEGIN ELSIF typemod <= 7 THEN max_length = 5; END IF; WHEN 'timestamp' THEN max_length = 8; + WHEN 'vector' THEN max_length = -1; -- dummy as varchar max ELSE max_length = typelen; END CASE; RETURN max_length; diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--3.4.0--3.5.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--3.4.0--3.5.0.sql index cac18bcf09..b70de1a5c1 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--3.4.0--3.5.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--3.4.0--3.5.0.sql @@ -2211,6 +2211,7 @@ AS SELECT WHERE FALSE; GRANT SELECT ON sys.availability_groups TO PUBLIC; + -- BABELFISH_SCHEMA_PERMISSIONS CREATE TABLE IF NOT EXISTS sys.babelfish_schema_permissions ( dbid smallint NOT NULL, @@ -2703,6 +2704,7 @@ BEGIN ELSIF typemod <= 7 THEN max_length = 5; END IF; WHEN 'timestamp' THEN max_length = 8; + WHEN 'vector' THEN max_length = -1; -- dummy as varchar max ELSE max_length = typelen; END CASE; RETURN max_length; @@ -2761,7 +2763,7 @@ $$SELECT THEN 1073741823 WHEN type = 'sysname' THEN 128 - WHEN type IN ('xml', 'geometry', 'geography') + WHEN type IN ('xml', 'vector', 'geometry', 'geography') THEN -1 WHEN type = 'sql_variant' THEN 0 @@ -2810,6 +2812,7 @@ BEGIN WHEN 'sql_variant' THEN tds_id = 98; WHEN 'datetimeoffset' THEN tds_id = 43; WHEN 'timestamp' THEN tds_id = 173; + WHEN 'vector' THEN tds_id = 167; -- Same as varchar WHEN 'geometry' THEN tds_id = 240; WHEN 'geography' THEN tds_id = 240; ELSE tds_id = 0; diff --git a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-epilogue.y.c b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-epilogue.y.c index 4c5a6346ba..3a70f625d6 100644 --- a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-epilogue.y.c +++ b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-epilogue.y.c @@ -1886,8 +1886,8 @@ tsql_index_nulls_order(List *indexParams, const char *accessMethod) if (indexElem->nulls_ordering != SORTBY_NULLS_DEFAULT) continue; - /* GIN indexes don't support NULLS FIRST/LAST options */ - if (strcmp(accessMethod, "gin") == 0) + /* GIN, HNSW and IVFFLAT indexes don't support NULLS FIRST/LAST options */ + if (strcmp(accessMethod, "gin") == 0 || strcmp(accessMethod, "hnsw") == 0 || strcmp(accessMethod, "ivfflat") == 0) return; switch (indexElem->ordering) diff --git a/contrib/babelfishpg_tsql/src/datatype_info.h b/contrib/babelfishpg_tsql/src/datatype_info.h index 5007d25cfd..2ac68d152e 100644 --- a/contrib/babelfishpg_tsql/src/datatype_info.h +++ b/contrib/babelfishpg_tsql/src/datatype_info.h @@ -4,7 +4,7 @@ #define NULLVAL PG_INT32_MIN #define NULLVAL_STR "NULL" -#define DATATYPE_INFO_TABLE_ROWS 39 +#define DATATYPE_INFO_TABLE_ROWS 40 typedef struct DatatypeInfo { @@ -488,6 +488,19 @@ static const DatatypeInfo datatype_info_table[DATATYPE_INFO_TABLE_ROWS] = { 0, 0, 9, 3, NULLVAL, NULLVAL, 22, 16, 111, "smalldatetime" }, + { + /* Dummy Entry for vector datatype since its not a TSQL datatype. */ + "vector", + NULLVAL, NULLVAL, NULLVAL, NULLVAL, + 0, + "'", + "'", + NULLVAL_STR, + 1, 0, 0, NULLVAL, 0, NULLVAL, + "vector", + NULLVAL, NULLVAL, NULLVAL, NULLVAL, NULLVAL, NULLVAL, NULLVAL, NULLVAL, NULLVAL, + "vector" + }, { "geometry", -4, -4, -151, -151, diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index afb51d57be..4f3c483832 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -31,6 +31,7 @@ #include "commands/createas.h" #include "commands/dbcommands.h" #include "commands/defrem.h" +#include "commands/extension.h" #include "commands/sequence.h" #include "commands/tablecmds.h" #include "commands/trigger.h" @@ -4266,6 +4267,9 @@ _PG_init(void) load_libraries("babelfishpg_common", NULL, false); init_and_check_common_utility(); + if (OidIsValid(get_extension_oid("vector", true))) + load_libraries("vector", NULL, false); + pg_bindtextdomain(TEXTDOMAIN); DefineCustomBoolVariable("babelfishpg_tsql.debug_parser", diff --git a/contrib/babelfishpg_tsql/src/procedures.c b/contrib/babelfishpg_tsql/src/procedures.c index 8c4e6b6d08..75d6558ba1 100644 --- a/contrib/babelfishpg_tsql/src/procedures.c +++ b/contrib/babelfishpg_tsql/src/procedures.c @@ -1768,6 +1768,27 @@ create_xp_instance_regread_in_master_dbo_internal(PG_FUNCTION_ARGS) PG_RETURN_INT32(0); } +/* + * For Long Term, we might want to restrict some of the + * extensions to be created only in sys. + */ +typedef struct allowed_extensions_data +{ + char *extn_name; + bool restricted_to_sys; +} allowed_extensions_data; + +/* Maintaining a proper defined list of supported extns. */ +const allowed_extensions_data allowed_extns[] = +{ + {"pg_stat_statements", false}, + {"tds_fdw", false}, + {"fuzzystrmatch", false}, + {"vector", true} +}; + +const int allowed_extns_size = sizeof(allowed_extns) / sizeof(allowed_extensions_data); + Datum sp_execute_postgresql(PG_FUNCTION_ARGS) { @@ -1777,8 +1798,6 @@ sp_execute_postgresql(PG_FUNCTION_ARGS) Node *parsetree; size_t len; PlannedStmt *wrapper; - const char *allowed_extns[] = {"pg_stat_statements", "tds_fdw", "fuzzystrmatch"}; - int allowed_extns_size = sizeof(allowed_extns) / sizeof(allowed_extns[0]); const char *saved_dialect = GetConfigOption("babelfishpg_tsql.sql_dialect", true, true); Oid current_user_id = GetUserId(); const char *saved_path = pstrdup(GetConfigOption("search_path", true, true)); @@ -1834,10 +1853,11 @@ sp_execute_postgresql(PG_FUNCTION_ARGS) ListCell *lc; char *schemaName = NULL; bool ext_found = false; + int i; - for(int i = 0; i < allowed_extns_size; i++) + for(i = 0; i < allowed_extns_size; i++) { - if(!(strcmp(crstmt->extname, allowed_extns[i]))) + if(!(strcmp(crstmt->extname, allowed_extns[i].extn_name))) { ext_found = true; break; @@ -1850,6 +1870,26 @@ sp_execute_postgresql(PG_FUNCTION_ARGS) errmsg("'%s' extension creation is not supported", crstmt->extname))); } + if (allowed_extns[i].restricted_to_sys) + { + bool explicit_opt = false; + + foreach (lc, crstmt->options) + { + DefElem *defel = (DefElem *) lfirst(lc); + + if (strcmp(defel->defname, "schema") == 0 && strcmp(defGetString(defel), "sys") == 0) + { + explicit_opt = true; + break; + } + } + + if (!explicit_opt) + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("'%s' extension creation is restricted to 'sys' schema", crstmt->extname))); + } + if (!superuser_arg(GetSessionUserId()) || !role_is_sa(GetSessionUserId())) { ereport(ERROR, diff --git a/contrib/babelfishpg_tsql/src/tsqlIface.cpp b/contrib/babelfishpg_tsql/src/tsqlIface.cpp index fc29947fd6..71582b572a 100644 --- a/contrib/babelfishpg_tsql/src/tsqlIface.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlIface.cpp @@ -2693,6 +2693,38 @@ class tsqlBuilder : public tsqlCommonMutator has_identity_function = false; } + void exitOrder_by_expression(TSqlParser::Order_by_expressionContext *ctx) override + { + /* + * If there are multiple Order by clauses then we do not need to append + * NULLS LAST since cummulative order bys do not choose an index scan. + */ + if (!(ctx->parent && ((TSqlParser::Order_by_clauseContext *)ctx->parent)->order_bys.size() == 1)) + return; + /* + * If the order by clause expression has a vector operator then we need to append + * NULLS LAST as the sort option such that vector index types can be chosen. This + * is done because the TSQL ordering is NULLS FIRST but for PG it's the opposite + * and the order does not matter for bit indexes. + */ + if (statementMutator && ctx->vector_operator()) + { + PLtsql_expr_query_mutator *mutator = statementMutator.get(); + if (ctx->ASC()) + { + mutator->add(ctx->ASC()->getSymbol()->getStopIndex()+1, "", " NULLS LAST"); + } + else if (ctx->DESC()) + { + mutator->add(ctx->DESC()->getSymbol()->getStopIndex()+1, "", " NULLS LAST"); + } + else + { + mutator->add(ctx->expression()[1]->stop->getStopIndex()+1, "", " NULLS LAST"); + } + } + } + void exitQuery_specification(TSqlParser::Query_specificationContext *ctx) override { // if select doesnt contains into but it contains identity we should throw error @@ -7301,7 +7333,7 @@ post_process_create_index(TSqlParser::Create_indexContext *ctx, PLtsql_stmt_exec removeTokenStringFromQuery(stmt->sqlstmt, ctx->clustered()->NONCLUSTERED(), baseCtx); if (ctx->COLUMNSTORE()) removeTokenStringFromQuery(stmt->sqlstmt, ctx->COLUMNSTORE(), baseCtx); - if (ctx->with_index_options()) + if (ctx->with_index_options() && !ctx->vector_index_method()) /* Vector indexes can have With clause. */ removeCtxStringFromQuery(stmt->sqlstmt, ctx->with_index_options(), baseCtx); return false; diff --git a/test/JDBC/expected/TestVectorDatatype.out b/test/JDBC/expected/TestVectorDatatype.out new file mode 100644 index 0000000000..613d385024 --- /dev/null +++ b/test/JDBC/expected/TestVectorDatatype.out @@ -0,0 +1,1491 @@ +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'vector' extension creation is restricted to 'sys' schema)~~ + + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go +~~START~~ +text +off +~~END~~ + + +-- functions +SELECT CAST('[1,2,3]' as vector) + '[4,5,6]'; +go +~~START~~ +varchar +[5,7,9] +~~END~~ + + +SELECT CAST('[3e38]' as vector) + '[3e38]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2,3]' as vector) - '[4,5,6]'; +go +~~START~~ +varchar +[-3,-3,-3] +~~END~~ + + +SELECT CAST('[-3e38]' as vector) - '[3e38]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2,3]' as vector) * '[4,5,6]'; +go +~~START~~ +varchar +[4,10,18] +~~END~~ + + +SELECT CAST('[1e37]' as vector) * '[1e37]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1e-37]' as vector) * '[1e-37]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: underflow)~~ + + +SELECT vector_dims('[1,2,3]'); +go +~~START~~ +int +3 +~~END~~ + + +SELECT round(cast(vector_norm('[1,1]') as numeric), 5); +go +~~START~~ +numeric +1.00000 +~~END~~ + + +SELECT vector_norm('[3,4]'); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT vector_norm('[0,1]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT vector_norm(Cast('[3e37,4e37]') as real); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'Cast' at line 1 and character position 19)~~ + + +SELECT l2_distance('[0,0]', '[3,4]'); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance('[0,0]', '[0,1]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_distance('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT l2_distance('[3e38]', '[-3e38]'); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT inner_product('[1,2]', '[3,4]'); +go +~~START~~ +float +11.0 +~~END~~ + + +SELECT inner_product('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT inner_product('[3e38]', '[3e38]'); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT cosine_distance('[1,2]', '[2,4]'); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance('[1,2]', '[0,0]'); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance('[1,1]', '[1,1]'); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance('[1,0]', '[0,2]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance('[1,1]', '[-1,-1]'); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT cosine_distance('[1,1]', '[1.1,1.1]'); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance('[1,1]', '[-1.1,-1.1]'); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance('[3e38]', '[3e38]'); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT l1_distance('[0,0]', '[3,4]'); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l1_distance('[0,0]', '[0,1]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l1_distance('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT l1_distance('[3e38]', '[-3e38]'); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT vector_avg(array_agg(n)) FROM generate_series(1, 16002) n; +go +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector cannot have more than 16000 dimensions)~~ + + + +-- cast. has all arrays can prune maybe use array_to_vector +SELECT CAST(CAST('{NULL}' as real[]) as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'CAST' at line 2 and character position 12)~~ + + +SELECT CAST(CAST('{NaN}' as real[]) as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'CAST' at line 1 and character position 12)~~ + + +SELECT CAST(CAST('{Infinity}' as real[]) as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'CAST' at line 1 and character position 12)~~ + + +SELECT CAST(array_agg(n) as vector) FROM generate_series(1, 1600) n; +go +~~START~~ +varchar +[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600] +~~END~~ + + +SELECT CAST(array_agg(n) as vector) FROM generate_series(1, 16001) n; +go +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector cannot have more than 16000 dimensions)~~ + + +SELECT array_to_vector(array_agg(n), 1600, false) FROM generate_series(1, 1600) n +go +~~START~~ +varchar +[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600] +~~END~~ + + +SELECT array_to_vector(array_agg(n), 16001, false) FROM generate_series(1, 16001) n; +go +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector cannot have more than 16000 dimensions)~~ + + +-- btree +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table (val); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table WHERE val = '[1,2,3]'; +go +~~START~~ +varchar +[1,2,3] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table WHERE val = '[1,2,3]' +Index Only Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=1 loops=1) + Index Cond: (val = '[1,2,3]'::vector) + Heap Fetches: 1 +~~END~~ + + +SELECT TOP 1 * FROM vector_table ORDER BY val; +go +~~START~~ +varchar + +~~END~~ + +~~START~~ +text +Query Text: SELECT TOP 1 * FROM vector_table ORDER BY val +Limit (actual rows=1 loops=1) + -> Index Only Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=1 loops=1) + Heap Fetches: 1 +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw_cosine +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING hnsw (val vector_cosine_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]'; +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=2 loops=1) + Order By: (val <=> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]') t2; +go +~~START~~ +int +2 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=2 loops=1) + Order By: (val <=> '[0,0,0]'::vector) +~~END~~ + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +2 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=2 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw_ip +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING hnsw (val vector_ip_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <#> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]') t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <#> '[0,0,0]'::vector) +~~END~~ + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw_l2 +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING hnsw (val vector_l2_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <-> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]') t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <-> '[0,0,0]'::vector) +~~END~~ + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw options +CREATE TABLE vector_table (val vector(3)); +go + +CREATE INDEX idx1 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 1); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 1 out of bounds for option "m")~~ + + +CREATE INDEX idx2 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 101); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 101 out of bounds for option "m")~~ + + +CREATE INDEX idx3 ON vector_table USING hnsw (val vector_l2_ops) WITH (ef_construction = 3); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 3 out of bounds for option "ef_construction")~~ + + +CREATE INDEX idx4 ON vector_table USING hnsw (val vector_l2_ops) WITH (ef_construction = 1001); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 1001 out of bounds for option "ef_construction")~~ + + +CREATE INDEX idx5 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 16, ef_construction = 31); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: ef_construction must be greater than or equal to 2 * m)~~ + + +Select current_setting('hnsw.ef_search') +go +~~START~~ +text +40 +~~END~~ + + +SELECT set_config('hnsw.ef_search', '0', false) +go +~~START~~ +text +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 0 is outside the valid range for parameter "hnsw.ef_search" (1 .. 1000))~~ + + +SELECT set_config('hnsw.ef_search', '1001', false) +go +~~START~~ +text +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 1001 is outside the valid range for parameter "hnsw.ef_search" (1 .. 1000))~~ + + +DROP TABLE vector_table; +go + +-- ivfflat cosine +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]'; +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +[1,2,4] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <=> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]') t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <=> '[0,0,0]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- ivfflat ip +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx2 ON vector_table USING ivfflat (val vector_ip_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,4] +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]' NULLS LAST +Index Scan using idx2vector_table8408d573e4ed8cfc5bc30f15b5393f14 on vector_table (actual rows=4 loops=1) + Order By: (val <#> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]') t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idx2vector_table8408d573e4ed8cfc5bc30f15b5393f14 on vector_table (actual rows=4 loops=1) + Order By: (val <#> '[0,0,0]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idx2vector_table8408d573e4ed8cfc5bc30f15b5393f14 on vector_table (actual rows=4 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- ivfflat l2 +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=4 loops=1) + Order By: (val <-> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]') t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=4 loops=1) + Order By: (val <-> '[0,0,0]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + + +-- ivfflat options +CREATE TABLE vector_table (val vector(3)); +go + +CREATE INDEX idx1 ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 0); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 0 out of bounds for option "lists")~~ + + +CREATE INDEX idx2 ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 32769); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 32769 out of bounds for option "lists")~~ + + +Select current_setting('ivfflat.probes') +go +~~START~~ +text +1 +~~END~~ + + +DROP TABLE vector_table; +go + +-- input +SELECT CAST('[1,2,3]' as vector); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[-1,-2,-3]' as vector); +go +~~START~~ +varchar +[-1,-2,-3] +~~END~~ + + +SELECT CAST('[1.,2.,3.]' as vector); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST(' [ 1, 2 , 3 ] ' as vector); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[1.23456]' as vector); +go +~~START~~ +varchar +[1.23456] +~~END~~ + + +SELECT CAST('[hello,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[hello,1]")~~ + + +SELECT CAST('[NaN,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NaN not allowed in vector)~~ + + +SELECT CAST('[Infinity,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in vector)~~ + + +SELECT CAST('[-Infinity,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in vector)~~ + + +SELECT CAST('[1.5e38,-1.5e38]' as vector); +go +~~START~~ +varchar +[1.5e+38,-1.5e+38] +~~END~~ + + +SELECT CAST('[1.5e+38,-1.5e+38]' as vector); +go +~~START~~ +varchar +[1.5e+38,-1.5e+38] +~~END~~ + + +SELECT CAST('[1.5e-38,-1.5e-38]' as vector); +go +~~START~~ +varchar +[1.5e-38,-1.5e-38] +~~END~~ + + +SELECT CAST('[4e38,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in vector)~~ + + +SELECT CAST('[1,2,3' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[1,2,3")~~ + + +SELECT CAST('[1,2,3]9' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[1,2,3]9")~~ + + +SELECT CAST('1,2,3' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "1,2,3")~~ + + +SELECT CAST('' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "")~~ + + +SELECT CAST('[' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[")~~ + + +SELECT CAST('[,' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[,")~~ + + +SELECT CAST('[]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector must have at least 1 dimension)~~ + + +SELECT CAST('[1,]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[1,]")~~ + + +SELECT CAST('[1a]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[1a]")~~ + + +SELECT CAST('[1,,3]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[1,,3]")~~ + + +SELECT CAST('[1, ,3]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[1, ,3]")~~ + + +SELECT CAST('[1,2,3]' as vector(2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: expected 2 dimensions, not 3)~~ + + +-- cummulative order by index/seq scan tests +CREATE TABLE vector_table1 (a int, val vector(3)); +go + +CREATE TABLE vector_table2 (a int, val vector(3)); +go + +CREATE TABLE table3 (a int, b int); +go + +INSERT INTO vector_table1 VALUES (1, '[0,0,0]'), (3, '[1,2,3]'),(NULL, NULL), (2, '[1,1,1]'); +INSERT INTO vector_table2 VALUES (1, '[0,0,0]'), (3, '[1,2,3]'),(NULL, NULL), (2, '[1,1,1]'); +INSERT INTO table3 (1, 3), (3, 5), (NULL, NULL), (2, 4); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '1' at line 3 and character position 20)~~ + + +CREATE INDEX idx ON vector_table1 USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +CREATE INDEX idx ON vector_table2 USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +go + +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table1 ORDER BY val <=> '[3,3,3]'; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table1 ORDER BY val <=> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table17f9bec28bc8902d45d905788d7aa59a1 on vector_table1 (actual rows=0 loops=1) + Order By: (val <=> '[3,3,3]'::vector) +~~END~~ + + +-- single column order, should use index scan thus NULLS LAST +SELECT t1.*, t2.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]'; +go +~~START~~ +int#!#varchar#!#int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.*, t2.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]' NULLS LAST +Nested Loop (actual rows=0 loops=1) + Join Filter: (t1.a = t2.a) + -> Index Scan using idxvector_table17f9bec28bc8902d45d905788d7aa59a1 on vector_table1 t1 (actual rows=0 loops=1) + Order By: (val <=> '[0,0,0]'::vector) + -> Materialize (never executed) + -> Seq Scan on vector_table2 t2 (never executed) +~~END~~ + + +-- more than one column order, should use seq scan NULLS FIRST +SELECT t1.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]', t2.val <=> '[1,1,1]'; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]', t2.val <=> '[1,1,1]' +Sort (actual rows=0 loops=1) + Sort Key: ((t1.val <=> '[0,0,0]'::vector)) NULLS FIRST, ((t2.val <=> '[1,1,1]'::vector)) NULLS FIRST + Sort Method: quicksort Memory: 25kB + -> Merge Join (actual rows=0 loops=1) + Merge Cond: (t1.a = t2.a) + -> Sort (actual rows=0 loops=1) + Sort Key: t1.a + Sort Method: quicksort Memory: 25kB + -> Seq Scan on vector_table1 t1 (actual rows=0 loops=1) + -> Sort (never executed) + Sort Key: t2.a + -> Seq Scan on vector_table2 t2 (never executed) +~~END~~ + + +SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]'; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]' NULLS LAST +Nested Loop (actual rows=0 loops=1) + Join Filter: (t1.a = t2.a) + -> Index Scan using idxvector_table17f9bec28bc8902d45d905788d7aa59a1 on vector_table1 t1 (actual rows=0 loops=1) + Order By: (val <=> '[0,0,0]'::vector) + -> Materialize (never executed) + -> Seq Scan on table3 t2 (never executed) +~~END~~ + + +SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]', t2.a; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]', t2.a +Sort (actual rows=0 loops=1) + Sort Key: ((t1.val <=> '[0,0,0]'::vector)) NULLS FIRST, t1.a NULLS FIRST + Sort Method: quicksort Memory: 25kB + -> Merge Join (actual rows=0 loops=1) + Merge Cond: (t1.a = t2.a) + -> Sort (actual rows=0 loops=1) + Sort Key: t1.a + Sort Method: quicksort Memory: 25kB + -> Seq Scan on vector_table1 t1 (actual rows=0 loops=1) + -> Sort (never executed) + Sort Key: t2.a + -> Seq Scan on table3 t2 (never executed) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +DROP TABLE vector_table1; +DROP TABLE vector_table2; +DROP TABLE table3; +go + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'vector'; +go +~~START~~ +int +1 +~~END~~ + + +create procedure vector_proc_1 @a vector, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'vector_proc_1' +go +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +vector_db#!#dbo#!#vector_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +vector_db#!#dbo#!#vector_proc_1;1#!#@a#!#1#!##!#vector#!#0#!#-1#!#0#!##!##!##!##!##!##!##!#1#!#NO#!# +vector_db#!#dbo#!#vector_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +drop procedure vector_proc_1; +go + +create table t(a vector(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#int#!#nvarchar#!#varchar#!#nvarchar#!#int#!#int#!#tinyint#!#smallint#!#int#!#smallint#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +vector_db#!#dbo#!#t#!#a#!#1#!##!#YES#!#vector#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!##!# +vector_db#!#dbo#!#t#!#b#!#2#!##!#YES#!#varchar#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# +~~END~~ + +select count(*) from sys.columns where object_id = sys.object_id('t') +go +~~START~~ +int +2 +~~END~~ + +drop table t; +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go diff --git a/test/JDBC/expected/babel_typecode.out b/test/JDBC/expected/babel_typecode.out index 482272a07e..9bd049143a 100644 --- a/test/JDBC/expected/babel_typecode.out +++ b/test/JDBC/expected/babel_typecode.out @@ -36,6 +36,7 @@ sys#!#decimal#!#decimal#!#5#!#30#!#5 sys#!#sysname#!#sysname#!#5#!#31#!#5 sys#!#rowversion#!#timestamp#!#8#!#32#!#3 sys#!#timestamp#!#timestamp#!#8#!#33#!#3 +sys#!#vector#!#vector#!#9#!#34#!#3 sys#!#geometry#!#geometry#!#5#!#34#!#1 sys#!#geography#!#geography#!#5#!#35#!#1 ~~END~~ diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestVectorDatatype.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestVectorDatatype.out new file mode 100644 index 0000000000..de3ff14719 --- /dev/null +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/TestVectorDatatype.out @@ -0,0 +1,1491 @@ +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'vector' extension creation is restricted to 'sys' schema)~~ + + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go +~~START~~ +text +off +~~END~~ + + +-- functions +SELECT CAST('[1,2,3]' as vector) + '[4,5,6]'; +go +~~START~~ +varchar +[5,7,9] +~~END~~ + + +SELECT CAST('[3e38]' as vector) + '[3e38]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2,3]' as vector) - '[4,5,6]'; +go +~~START~~ +varchar +[-3,-3,-3] +~~END~~ + + +SELECT CAST('[-3e38]' as vector) - '[3e38]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2,3]' as vector) * '[4,5,6]'; +go +~~START~~ +varchar +[4,10,18] +~~END~~ + + +SELECT CAST('[1e37]' as vector) * '[1e37]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1e-37]' as vector) * '[1e-37]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: underflow)~~ + + +SELECT vector_dims('[1,2,3]'); +go +~~START~~ +int +3 +~~END~~ + + +SELECT round(cast(vector_norm('[1,1]') as numeric), 5); +go +~~START~~ +numeric +1.00000 +~~END~~ + + +SELECT vector_norm('[3,4]'); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT vector_norm('[0,1]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT vector_norm(Cast('[3e37,4e37]') as real); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'Cast' at line 1 and character position 19)~~ + + +SELECT l2_distance('[0,0]', '[3,4]'); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance('[0,0]', '[0,1]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_distance('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT l2_distance('[3e38]', '[-3e38]'); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT inner_product('[1,2]', '[3,4]'); +go +~~START~~ +float +11.0 +~~END~~ + + +SELECT inner_product('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT inner_product('[3e38]', '[3e38]'); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT cosine_distance('[1,2]', '[2,4]'); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance('[1,2]', '[0,0]'); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance('[1,1]', '[1,1]'); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance('[1,0]', '[0,2]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance('[1,1]', '[-1,-1]'); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT cosine_distance('[1,1]', '[1.1,1.1]'); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance('[1,1]', '[-1.1,-1.1]'); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance('[3e38]', '[3e38]'); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT l1_distance('[0,0]', '[3,4]'); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l1_distance('[0,0]', '[0,1]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l1_distance('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT l1_distance('[3e38]', '[-3e38]'); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT vector_avg(array_agg(n)) FROM generate_series(1, 16002) n; +go +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector cannot have more than 16000 dimensions)~~ + + + +-- cast. has all arrays can prune maybe use array_to_vector +SELECT CAST(CAST('{NULL}' as real[]) as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'CAST' at line 2 and character position 12)~~ + + +SELECT CAST(CAST('{NaN}' as real[]) as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'CAST' at line 1 and character position 12)~~ + + +SELECT CAST(CAST('{Infinity}' as real[]) as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'CAST' at line 1 and character position 12)~~ + + +SELECT CAST(array_agg(n) as vector) FROM generate_series(1, 1600) n; +go +~~START~~ +varchar +[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600] +~~END~~ + + +SELECT CAST(array_agg(n) as vector) FROM generate_series(1, 16001) n; +go +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector cannot have more than 16000 dimensions)~~ + + +SELECT array_to_vector(array_agg(n), 1600, false) FROM generate_series(1, 1600) n +go +~~START~~ +varchar +[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600] +~~END~~ + + +SELECT array_to_vector(array_agg(n), 16001, false) FROM generate_series(1, 16001) n; +go +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector cannot have more than 16000 dimensions)~~ + + +-- btree +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table (val); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table WHERE val = '[1,2,3]'; +go +~~START~~ +varchar +[1,2,3] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table WHERE val = '[1,2,3]' +Index Only Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=1 loops=1) + Index Cond: (val = '[1,2,3]'::vector) + Heap Fetches: 1 +~~END~~ + + +SELECT TOP 1 * FROM vector_table ORDER BY val; +go +~~START~~ +varchar + +~~END~~ + +~~START~~ +text +Query Text: SELECT TOP 1 * FROM vector_table ORDER BY val +Limit (actual rows=1 loops=1) + -> Index Only Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=1 loops=1) + Heap Fetches: 1 +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw_cosine +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING hnsw (val vector_cosine_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]'; +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=2 loops=1) + Order By: (val <=> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]') t2; +go +~~START~~ +int +2 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=2 loops=1) + Order By: (val <=> '[0,0,0]'::vector) +~~END~~ + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +2 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=2 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw_ip +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING hnsw (val vector_ip_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <#> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]') t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <#> '[0,0,0]'::vector) +~~END~~ + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw_l2 +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING hnsw (val vector_l2_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <-> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]') t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <-> '[0,0,0]'::vector) +~~END~~ + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw options +CREATE TABLE vector_table (val vector(3)); +go + +CREATE INDEX idx1 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 1); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 1 out of bounds for option "m")~~ + + +CREATE INDEX idx2 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 101); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 101 out of bounds for option "m")~~ + + +CREATE INDEX idx3 ON vector_table USING hnsw (val vector_l2_ops) WITH (ef_construction = 3); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 3 out of bounds for option "ef_construction")~~ + + +CREATE INDEX idx4 ON vector_table USING hnsw (val vector_l2_ops) WITH (ef_construction = 1001); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 1001 out of bounds for option "ef_construction")~~ + + +CREATE INDEX idx5 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 16, ef_construction = 31); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: ef_construction must be greater than or equal to 2 * m)~~ + + +Select current_setting('hnsw.ef_search') +go +~~START~~ +text +40 +~~END~~ + + +SELECT set_config('hnsw.ef_search', '0', false) +go +~~START~~ +text +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 0 is outside the valid range for parameter "hnsw.ef_search" (1 .. 1000))~~ + + +SELECT set_config('hnsw.ef_search', '1001', false) +go +~~START~~ +text +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 1001 is outside the valid range for parameter "hnsw.ef_search" (1 .. 1000))~~ + + +DROP TABLE vector_table; +go + +-- ivfflat cosine +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]'; +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +[1,2,4] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <=> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]') t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <=> '[0,0,0]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- ivfflat ip +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx2 ON vector_table USING ivfflat (val vector_ip_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,4] +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]' NULLS LAST +Index Scan using idx2vector_table8408d573e4ed8cfc5bc30f15b5393f14 on vector_table (actual rows=4 loops=1) + Order By: (val <#> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]') t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idx2vector_table8408d573e4ed8cfc5bc30f15b5393f14 on vector_table (actual rows=4 loops=1) + Order By: (val <#> '[0,0,0]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idx2vector_table8408d573e4ed8cfc5bc30f15b5393f14 on vector_table (actual rows=4 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- ivfflat l2 +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=4 loops=1) + Order By: (val <-> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]') t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]' NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=4 loops=1) + Order By: (val <-> '[0,0,0]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + + +-- ivfflat options +CREATE TABLE vector_table (val vector(3)); +go + +CREATE INDEX idx1 ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 0); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 0 out of bounds for option "lists")~~ + + +CREATE INDEX idx2 ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 32769); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 32769 out of bounds for option "lists")~~ + + +Select current_setting('ivfflat.probes') +go +~~START~~ +text +1 +~~END~~ + + +DROP TABLE vector_table; +go + +-- input +SELECT CAST('[1,2,3]' as vector); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[-1,-2,-3]' as vector); +go +~~START~~ +varchar +[-1,-2,-3] +~~END~~ + + +SELECT CAST('[1.,2.,3.]' as vector); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST(' [ 1, 2 , 3 ] ' as vector); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[1.23456]' as vector); +go +~~START~~ +varchar +[1.23456] +~~END~~ + + +SELECT CAST('[hello,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[hello,1]")~~ + + +SELECT CAST('[NaN,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NaN not allowed in vector)~~ + + +SELECT CAST('[Infinity,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in vector)~~ + + +SELECT CAST('[-Infinity,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in vector)~~ + + +SELECT CAST('[1.5e38,-1.5e38]' as vector); +go +~~START~~ +varchar +[1.5e+38,-1.5e+38] +~~END~~ + + +SELECT CAST('[1.5e+38,-1.5e+38]' as vector); +go +~~START~~ +varchar +[1.5e+38,-1.5e+38] +~~END~~ + + +SELECT CAST('[1.5e-38,-1.5e-38]' as vector); +go +~~START~~ +varchar +[1.5e-38,-1.5e-38] +~~END~~ + + +SELECT CAST('[4e38,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in vector)~~ + + +SELECT CAST('[1,2,3' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[1,2,3")~~ + + +SELECT CAST('[1,2,3]9' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[1,2,3]9")~~ + + +SELECT CAST('1,2,3' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "1,2,3")~~ + + +SELECT CAST('' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "")~~ + + +SELECT CAST('[' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[")~~ + + +SELECT CAST('[,' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[,")~~ + + +SELECT CAST('[]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector must have at least 1 dimension)~~ + + +SELECT CAST('[1,]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[1,]")~~ + + +SELECT CAST('[1a]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[1a]")~~ + + +SELECT CAST('[1,,3]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[1,,3]")~~ + + +SELECT CAST('[1, ,3]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[1, ,3]")~~ + + +SELECT CAST('[1,2,3]' as vector(2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: expected 2 dimensions, not 3)~~ + + +-- cummulative order by index/seq scan tests +CREATE TABLE vector_table1 (a int, val vector(3)); +go + +CREATE TABLE vector_table2 (a int, val vector(3)); +go + +CREATE TABLE table3 (a int, b int); +go + +INSERT INTO vector_table1 VALUES (1, '[0,0,0]'), (3, '[1,2,3]'),(NULL, NULL), (2, '[1,1,1]'); +INSERT INTO vector_table2 VALUES (1, '[0,0,0]'), (3, '[1,2,3]'),(NULL, NULL), (2, '[1,1,1]'); +INSERT INTO table3 (1, 3), (3, 5), (NULL, NULL), (2, 4); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '1' at line 3 and character position 20)~~ + + +CREATE INDEX idx ON vector_table1 USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +CREATE INDEX idx ON vector_table2 USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +go + +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table1 ORDER BY val <=> '[3,3,3]'; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table1 ORDER BY val <=> '[3,3,3]' NULLS LAST +Index Scan using idxvector_table17f9bec28bc8902d45d905788d7aa59a1 on vector_table1 (actual rows=0 loops=1) + Order By: (val <=> '[3,3,3]'::vector) +~~END~~ + + +-- single column order, should use index scan thus NULLS LAST +SELECT t1.*, t2.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]'; +go +~~START~~ +int#!#varchar#!#int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.*, t2.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]' NULLS LAST +Nested Loop (actual rows=0 loops=1) + Join Filter: (t1.a = t2.a) + -> Index Scan using idxvector_table17f9bec28bc8902d45d905788d7aa59a1 on vector_table1 t1 (actual rows=0 loops=1) + Order By: (val <=> '[0,0,0]'::vector) + -> Materialize (never executed) + -> Seq Scan on vector_table2 t2 (never executed) +~~END~~ + + +-- more than one column order, should use seq scan NULLS FIRST +SELECT t1.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]', t2.val <=> '[1,1,1]'; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]', t2.val <=> '[1,1,1]' +Sort (actual rows=0 loops=1) + Sort Key: ((t1.val <=> '[0,0,0]'::vector)) NULLS FIRST, ((t2.val <=> '[1,1,1]'::vector)) NULLS FIRST + Sort Method: quicksort Memory: 25kB + -> Merge Join (actual rows=0 loops=1) + Merge Cond: (t1.a = t2.a) + -> Sort (actual rows=0 loops=1) + Sort Key: t1.a + Sort Method: quicksort Memory: 25kB + -> Seq Scan on vector_table1 t1 (actual rows=0 loops=1) + -> Sort (never executed) + Sort Key: t2.a + -> Seq Scan on vector_table2 t2 (never executed) +~~END~~ + + +SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]'; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]' NULLS LAST +Nested Loop (actual rows=0 loops=1) + Join Filter: (t1.a = t2.a) + -> Index Scan using idxvector_table17f9bec28bc8902d45d905788d7aa59a1 on vector_table1 t1 (actual rows=0 loops=1) + Order By: (val <=> '[0,0,0]'::vector) + -> Materialize (never executed) + -> Seq Scan on table3 t2 (never executed) +~~END~~ + + +SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]', t2.a; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]', t2.a +Sort (actual rows=0 loops=1) + Sort Key: ((t1.val <=> '[0,0,0]'::vector)) NULLS FIRST, t1.a NULLS FIRST + Sort Method: quicksort Memory: 25kB + -> Merge Join (actual rows=0 loops=1) + Merge Cond: (t1.a = t2.a) + -> Sort (actual rows=0 loops=1) + Sort Key: t1.a + Sort Method: quicksort Memory: 25kB + -> Seq Scan on vector_table1 t1 (actual rows=0 loops=1) + -> Sort (never executed) + Sort Key: t2.a + -> Seq Scan on table3 t2 (never executed) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +DROP TABLE vector_table1; +DROP TABLE vector_table2; +DROP TABLE table3; +go + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'vector'; +go +~~START~~ +int +1 +~~END~~ + + +create procedure vector_proc_1 @a vector, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'vector_proc_1' +go +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +vector_db#!#dbo#!#vector_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +vector_db#!#dbo#!#vector_proc_1;1#!#@a#!#1#!##!#vector#!#0#!#-1#!#0#!##!##!##!##!##!##!##!#1#!#NO#!# +vector_db#!#dbo#!#vector_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +drop procedure vector_proc_1; +go + +create table t(a vector(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#int#!#nvarchar#!#varchar#!#nvarchar#!#int#!#int#!#tinyint#!#smallint#!#int#!#smallint#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +vector_db#!#dbo#!#t#!#a#!#1#!##!#YES#!#vector#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!##!# +vector_db#!#dbo#!#t#!#b#!#2#!##!#YES#!#varchar#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!#chinese_prc_ci_as#!##!##!# +~~END~~ + +select count(*) from sys.columns where object_id = sys.object_id('t') +go +~~START~~ +int +2 +~~END~~ + +drop table t; +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go diff --git a/test/JDBC/expected/parallel_query/TestVectorDatatype.out b/test/JDBC/expected/parallel_query/TestVectorDatatype.out new file mode 100644 index 0000000000..0691155690 --- /dev/null +++ b/test/JDBC/expected/parallel_query/TestVectorDatatype.out @@ -0,0 +1,1566 @@ +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'vector' extension creation is restricted to 'sys' schema)~~ + + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +~~START~~ +text +off +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go +~~START~~ +text +off +~~END~~ + + +-- functions +SELECT CAST('[1,2,3]' as vector) + '[4,5,6]'; +go +~~START~~ +varchar +[5,7,9] +~~END~~ + + +SELECT CAST('[3e38]' as vector) + '[3e38]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2,3]' as vector) - '[4,5,6]'; +go +~~START~~ +varchar +[-3,-3,-3] +~~END~~ + + +SELECT CAST('[-3e38]' as vector) - '[3e38]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1,2,3]' as vector) * '[4,5,6]'; +go +~~START~~ +varchar +[4,10,18] +~~END~~ + + +SELECT CAST('[1e37]' as vector) * '[1e37]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: overflow)~~ + + +SELECT CAST('[1e-37]' as vector) * '[1e-37]'; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value out of range: underflow)~~ + + +SELECT vector_dims('[1,2,3]'); +go +~~START~~ +int +3 +~~END~~ + + +SELECT round(cast(vector_norm('[1,1]') as numeric), 5); +go +~~START~~ +numeric +1.00000 +~~END~~ + + +SELECT vector_norm('[3,4]'); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT vector_norm('[0,1]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT vector_norm(Cast('[3e37,4e37]') as real); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'Cast' at line 1 and character position 19)~~ + + +SELECT l2_distance('[0,0]', '[3,4]'); +go +~~START~~ +float +5.0 +~~END~~ + + +SELECT l2_distance('[0,0]', '[0,1]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l2_distance('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT l2_distance('[3e38]', '[-3e38]'); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT inner_product('[1,2]', '[3,4]'); +go +~~START~~ +float +11.0 +~~END~~ + + +SELECT inner_product('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT inner_product('[3e38]', '[3e38]'); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT cosine_distance('[1,2]', '[2,4]'); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance('[1,2]', '[0,0]'); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT cosine_distance('[1,1]', '[1,1]'); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance('[1,0]', '[0,2]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT cosine_distance('[1,1]', '[-1,-1]'); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT cosine_distance('[1,1]', '[1.1,1.1]'); +go +~~START~~ +float +0.0 +~~END~~ + + +SELECT cosine_distance('[1,1]', '[-1.1,-1.1]'); +go +~~START~~ +float +2.0 +~~END~~ + + +SELECT cosine_distance('[3e38]', '[3e38]'); +go +~~START~~ +float +NaN +~~END~~ + + +SELECT l1_distance('[0,0]', '[3,4]'); +go +~~START~~ +float +7.0 +~~END~~ + + +SELECT l1_distance('[0,0]', '[0,1]'); +go +~~START~~ +float +1.0 +~~END~~ + + +SELECT l1_distance('[1,2]', '[3]'); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: different vector dimensions 2 and 1)~~ + + +SELECT l1_distance('[3e38]', '[-3e38]'); +go +~~START~~ +float +Infinity +~~END~~ + + +SELECT vector_avg(array_agg(n)) FROM generate_series(1, 16002) n; +go +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector cannot have more than 16000 dimensions)~~ + + + +-- cast. has all arrays can prune maybe use array_to_vector +SELECT CAST(CAST('{NULL}' as real[]) as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'CAST' at line 2 and character position 12)~~ + + +SELECT CAST(CAST('{NaN}' as real[]) as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'CAST' at line 1 and character position 12)~~ + + +SELECT CAST(CAST('{Infinity}' as real[]) as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near 'CAST' at line 1 and character position 12)~~ + + +SELECT CAST(array_agg(n) as vector) FROM generate_series(1, 1600) n; +go +~~START~~ +varchar +[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600] +~~END~~ + + +SELECT CAST(array_agg(n) as vector) FROM generate_series(1, 16001) n; +go +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector cannot have more than 16000 dimensions)~~ + + +SELECT array_to_vector(array_agg(n), 1600, false) FROM generate_series(1, 1600) n +go +~~START~~ +varchar +[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600] +~~END~~ + + +SELECT array_to_vector(array_agg(n), 16001, false) FROM generate_series(1, 16001) n; +go +~~START~~ +varchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector cannot have more than 16000 dimensions)~~ + + +-- btree +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table (val); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table WHERE val = '[1,2,3]'; +go +~~START~~ +varchar +[1,2,3] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table WHERE val = '[1,2,3]' +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Only Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=1 loops=1) + Index Cond: (val = '[1,2,3]'::vector) + Heap Fetches: 1 +~~END~~ + + +SELECT TOP 1 * FROM vector_table ORDER BY val; +go +~~START~~ +varchar + +~~END~~ + +~~START~~ +text +Query Text: SELECT TOP 1 * FROM vector_table ORDER BY val +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Limit (actual rows=1 loops=1) + -> Index Only Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=1 loops=1) + Heap Fetches: 1 +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw_cosine +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING hnsw (val vector_cosine_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]'; +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]' NULLS LAST +Gather (actual rows=2 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=2 loops=1) + Order By: (val <=> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]') t2; +go +~~START~~ +int +2 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]' NULLS LAST) t2 +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=2 loops=1) + Order By: (val <=> '[0,0,0]'::vector) +~~END~~ + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +2 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=2 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw_ip +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING hnsw (val vector_ip_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]' NULLS LAST +Gather (actual rows=3 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <#> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]') t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]' NULLS LAST) t2 +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <#> '[0,0,0]'::vector) +~~END~~ + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw_l2 +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING hnsw (val vector_l2_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]' NULLS LAST +Gather (actual rows=3 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <-> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]') t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]' NULLS LAST) t2 +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <-> '[0,0,0]'::vector) +~~END~~ + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- hnsw options +CREATE TABLE vector_table (val vector(3)); +go + +CREATE INDEX idx1 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 1); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 1 out of bounds for option "m")~~ + + +CREATE INDEX idx2 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 101); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 101 out of bounds for option "m")~~ + + +CREATE INDEX idx3 ON vector_table USING hnsw (val vector_l2_ops) WITH (ef_construction = 3); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 3 out of bounds for option "ef_construction")~~ + + +CREATE INDEX idx4 ON vector_table USING hnsw (val vector_l2_ops) WITH (ef_construction = 1001); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 1001 out of bounds for option "ef_construction")~~ + + +CREATE INDEX idx5 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 16, ef_construction = 31); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: ef_construction must be greater than or equal to 2 * m)~~ + + +Select current_setting('hnsw.ef_search') +go +~~START~~ +text +40 +~~END~~ + + +SELECT set_config('hnsw.ef_search', '0', false) +go +~~START~~ +text +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 0 is outside the valid range for parameter "hnsw.ef_search" (1 .. 1000))~~ + + +SELECT set_config('hnsw.ef_search', '1001', false) +go +~~START~~ +text +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 1001 is outside the valid range for parameter "hnsw.ef_search" (1 .. 1000))~~ + + +DROP TABLE vector_table; +go + +-- ivfflat cosine +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]'; +go +~~START~~ +varchar +[1,1,1] +[1,2,3] +[1,2,4] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]' NULLS LAST +Gather (actual rows=3 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <=> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]') t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]' NULLS LAST) t2 +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <=> '[0,0,0]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +3 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=3 loops=1) + Order By: (val <=> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- ivfflat ip +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx2 ON vector_table USING ivfflat (val vector_ip_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,4] +[1,2,3] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]' NULLS LAST +Gather (actual rows=4 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idx2vector_table8408d573e4ed8cfc5bc30f15b5393f14 on vector_table (actual rows=4 loops=1) + Order By: (val <#> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]') t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]' NULLS LAST) t2 +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Index Scan using idx2vector_table8408d573e4ed8cfc5bc30f15b5393f14 on vector_table (actual rows=4 loops=1) + Order By: (val <#> '[0,0,0]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idx2vector_table8408d573e4ed8cfc5bc30f15b5393f14 on vector_table (actual rows=4 loops=1) + Order By: (val <#> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + +-- ivfflat l2 +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go +~~ROW COUNT: 4~~ + + +CREATE INDEX idx ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go +~~ROW COUNT: 1~~ + + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + +SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]'; +go +~~START~~ +varchar +[1,2,3] +[1,2,4] +[1,1,1] +[0,0,0] +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]' NULLS LAST +Gather (actual rows=4 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=4 loops=1) + Order By: (val <-> '[3,3,3]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]') t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]' NULLS LAST) t2 +Gather (actual rows=1 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=4 loops=1) + Order By: (val <-> '[0,0,0]'::vector) +~~END~~ + + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector))) t2; +go +~~START~~ +int +4 +~~END~~ + +~~START~~ +text +Query Text: SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector)) NULLS LAST) t2 +Aggregate (actual rows=1 loops=1) + -> Index Scan using idxvector_table7f9bec28bc8902d45d905788d7aa59a1 on vector_table (actual rows=4 loops=1) + Order By: (val <-> $0) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go +~~START~~ +text +on +~~END~~ + + + +-- ivfflat options +CREATE TABLE vector_table (val vector(3)); +go + +CREATE INDEX idx1 ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 0); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 0 out of bounds for option "lists")~~ + + +CREATE INDEX idx2 ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 32769); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: value 32769 out of bounds for option "lists")~~ + + +Select current_setting('ivfflat.probes') +go +~~START~~ +text +1 +~~END~~ + + +DROP TABLE vector_table; +go + +-- input +SELECT CAST('[1,2,3]' as vector); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[-1,-2,-3]' as vector); +go +~~START~~ +varchar +[-1,-2,-3] +~~END~~ + + +SELECT CAST('[1.,2.,3.]' as vector); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST(' [ 1, 2 , 3 ] ' as vector); +go +~~START~~ +varchar +[1,2,3] +~~END~~ + + +SELECT CAST('[1.23456]' as vector); +go +~~START~~ +varchar +[1.23456] +~~END~~ + + +SELECT CAST('[hello,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[hello,1]")~~ + + +SELECT CAST('[NaN,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: NaN not allowed in vector)~~ + + +SELECT CAST('[Infinity,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in vector)~~ + + +SELECT CAST('[-Infinity,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in vector)~~ + + +SELECT CAST('[1.5e38,-1.5e38]' as vector); +go +~~START~~ +varchar +[1.5e+38,-1.5e+38] +~~END~~ + + +SELECT CAST('[1.5e+38,-1.5e+38]' as vector); +go +~~START~~ +varchar +[1.5e+38,-1.5e+38] +~~END~~ + + +SELECT CAST('[1.5e-38,-1.5e-38]' as vector); +go +~~START~~ +varchar +[1.5e-38,-1.5e-38] +~~END~~ + + +SELECT CAST('[4e38,1]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: infinite value not allowed in vector)~~ + + +SELECT CAST('[1,2,3' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[1,2,3")~~ + + +SELECT CAST('[1,2,3]9' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[1,2,3]9")~~ + + +SELECT CAST('1,2,3' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "1,2,3")~~ + + +SELECT CAST('' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "")~~ + + +SELECT CAST('[' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[")~~ + + +SELECT CAST('[,' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[,")~~ + + +SELECT CAST('[]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: vector must have at least 1 dimension)~~ + + +SELECT CAST('[1,]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[1,]")~~ + + +SELECT CAST('[1a]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[1a]")~~ + + +SELECT CAST('[1,,3]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: malformed vector literal: "[1,,3]")~~ + + +SELECT CAST('[1, ,3]' as vector); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type vector: "[1, ,3]")~~ + + +SELECT CAST('[1,2,3]' as vector(2)); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: expected 2 dimensions, not 3)~~ + + +-- cummulative order by index/seq scan tests +CREATE TABLE vector_table1 (a int, val vector(3)); +go + +CREATE TABLE vector_table2 (a int, val vector(3)); +go + +CREATE TABLE table3 (a int, b int); +go + +INSERT INTO vector_table1 VALUES (1, '[0,0,0]'), (3, '[1,2,3]'),(NULL, NULL), (2, '[1,1,1]'); +INSERT INTO vector_table2 VALUES (1, '[0,0,0]'), (3, '[1,2,3]'),(NULL, NULL), (2, '[1,1,1]'); +INSERT INTO table3 (1, 3), (3, 5), (NULL, NULL), (2, 4); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '1' at line 3 and character position 20)~~ + + +CREATE INDEX idx ON vector_table1 USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +CREATE INDEX idx ON vector_table2 USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +go + +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +~~START~~ +text +off +~~END~~ + +~~START~~ +text +Query Text: SELECT set_config('enable_seqscan', 'off', false) +Result (actual rows=1 loops=1) +~~END~~ + + +SELECT * FROM vector_table1 ORDER BY val <=> '[3,3,3]'; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT * FROM vector_table1 ORDER BY val <=> '[3,3,3]' NULLS LAST +Gather (actual rows=0 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Index Scan using idxvector_table17f9bec28bc8902d45d905788d7aa59a1 on vector_table1 (actual rows=0 loops=1) + Order By: (val <=> '[3,3,3]'::vector) +~~END~~ + + +-- single column order, should use index scan thus NULLS LAST +SELECT t1.*, t2.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]'; +go +~~START~~ +int#!#varchar#!#int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.*, t2.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]' NULLS LAST +Gather (actual rows=0 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Nested Loop (actual rows=0 loops=1) + Join Filter: (t1.a = t2.a) + -> Index Scan using idxvector_table17f9bec28bc8902d45d905788d7aa59a1 on vector_table1 t1 (actual rows=0 loops=1) + Order By: (val <=> '[0,0,0]'::vector) + -> Materialize (never executed) + -> Seq Scan on vector_table2 t2 (never executed) +~~END~~ + + +-- more than one column order, should use seq scan NULLS FIRST +SELECT t1.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]', t2.val <=> '[1,1,1]'; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]', t2.val <=> '[1,1,1]' +Gather Merge (actual rows=0 loops=1) + Workers Planned: 3 + Workers Launched: 3 + -> Sort (actual rows=0 loops=4) + Sort Key: ((t1.val <=> '[0,0,0]'::vector)) NULLS FIRST, ((t2.val <=> '[1,1,1]'::vector)) NULLS FIRST + Sort Method: quicksort Memory: 25kB + Worker 0: Sort Method: quicksort Memory: 25kB + Worker 1: Sort Method: quicksort Memory: 25kB + Worker 2: Sort Method: quicksort Memory: 25kB + -> Parallel Hash Join (actual rows=0 loops=4) + Hash Cond: (t1.a = t2.a) + -> Parallel Seq Scan on vector_table1 t1 (never executed) + -> Parallel Hash (actual rows=0 loops=4) + Buckets: 2048 Batches: 1 Memory Usage: 0kB + -> Parallel Seq Scan on vector_table2 t2 (actual rows=0 loops=1) +~~END~~ + + +SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]'; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]' NULLS LAST +Gather (actual rows=0 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Nested Loop (actual rows=0 loops=1) + Join Filter: (t1.a = t2.a) + -> Index Scan using idxvector_table17f9bec28bc8902d45d905788d7aa59a1 on vector_table1 t1 (actual rows=0 loops=1) + Order By: (val <=> '[0,0,0]'::vector) + -> Materialize (never executed) + -> Seq Scan on table3 t2 (never executed) +~~END~~ + + +SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]', t2.a; +go +~~START~~ +int#!#varchar +~~END~~ + +~~START~~ +text +Query Text: SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]', t2.a +Gather (actual rows=0 loops=1) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Sort (actual rows=0 loops=1) + Sort Key: ((t1.val <=> '[0,0,0]'::vector)) NULLS FIRST, t1.a NULLS FIRST + Worker 0: Sort Method: quicksort Memory: 25kB + -> Merge Join (actual rows=0 loops=1) + Merge Cond: (t1.a = t2.a) + -> Sort (actual rows=0 loops=1) + Sort Key: t1.a + Worker 0: Sort Method: quicksort Memory: 25kB + -> Seq Scan on vector_table1 t1 (actual rows=0 loops=1) + -> Sort (never executed) + Sort Key: t2.a + -> Seq Scan on table3 t2 (never executed) +~~END~~ + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +DROP TABLE vector_table1; +DROP TABLE vector_table2; +DROP TABLE table3; +go + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +~~START~~ +text +on +~~END~~ + +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go +~~START~~ +text +on +~~END~~ + + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'vector'; +go +~~START~~ +int +1 +~~END~~ + + +create procedure vector_proc_1 @a vector, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'vector_proc_1' +go +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +vector_db#!#dbo#!#vector_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +vector_db#!#dbo#!#vector_proc_1;1#!#@a#!#1#!##!#vector#!#0#!#-1#!#0#!##!##!##!##!##!##!##!#1#!#NO#!# +vector_db#!#dbo#!#vector_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +drop procedure vector_proc_1; +go + +create table t(a vector(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#int#!#nvarchar#!#varchar#!#nvarchar#!#int#!#int#!#tinyint#!#smallint#!#int#!#smallint#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +vector_db#!#dbo#!#t#!#a#!#1#!##!#YES#!#vector#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!##!# +vector_db#!#dbo#!#t#!#b#!#2#!##!#YES#!#varchar#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!#bbf_unicode_cp1_ci_as#!##!##!# +~~END~~ + +select count(*) from sys.columns where object_id = sys.object_id('t') +go +~~START~~ +int +2 +~~END~~ + +drop table t; +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO +~~START~~ +bool +t +~~END~~ + + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go diff --git a/test/JDBC/input/datatypes/TestVectorDatatype.mix b/test/JDBC/input/datatypes/TestVectorDatatype.mix new file mode 100644 index 0000000000..374393bb78 --- /dev/null +++ b/test/JDBC/input/datatypes/TestVectorDatatype.mix @@ -0,0 +1,567 @@ +-- parallel_query_expected +-- tsql +-- should throw error since vector is only allowed in sys +exec sp_execute_postgresql 'create extension vector'; +go + +exec sp_execute_postgresql 'create extension vector with schema sys'; +go + +create login vector_login with password='12345678' +go + +Alter server role sysadmin add member vector_login +go + +create database vector_db; +go + +use vector_db +go + +-- tsql user=vector_login password=12345678 +use vector_db; +go + +select set_config('babelfishpg_tsql.explain_costs', 'off', false); +go +select set_config('babelfishpg_tsql.explain_timing', 'off', false); +go +select set_config('babelfishpg_tsql.explain_summary', 'off', false); +go + +-- functions +SELECT CAST('[1,2,3]' as vector) + '[4,5,6]'; +go + +SELECT CAST('[3e38]' as vector) + '[3e38]'; +go + +SELECT CAST('[1,2,3]' as vector) - '[4,5,6]'; +go + +SELECT CAST('[-3e38]' as vector) - '[3e38]'; +go + +SELECT CAST('[1,2,3]' as vector) * '[4,5,6]'; +go + +SELECT CAST('[1e37]' as vector) * '[1e37]'; +go + +SELECT CAST('[1e-37]' as vector) * '[1e-37]'; +go + +SELECT vector_dims('[1,2,3]'); +go + +SELECT round(cast(vector_norm('[1,1]') as numeric), 5); +go + +SELECT vector_norm('[3,4]'); +go + +SELECT vector_norm('[0,1]'); +go + +SELECT vector_norm(Cast('[3e37,4e37]') as real); +go + +SELECT l2_distance('[0,0]', '[3,4]'); +go + +SELECT l2_distance('[0,0]', '[0,1]'); +go + +SELECT l2_distance('[1,2]', '[3]'); +go + +SELECT l2_distance('[3e38]', '[-3e38]'); +go + +SELECT inner_product('[1,2]', '[3,4]'); +go + +SELECT inner_product('[1,2]', '[3]'); +go + +SELECT inner_product('[3e38]', '[3e38]'); +go + +SELECT cosine_distance('[1,2]', '[2,4]'); +go + +SELECT cosine_distance('[1,2]', '[0,0]'); +go + +SELECT cosine_distance('[1,1]', '[1,1]'); +go + +SELECT cosine_distance('[1,0]', '[0,2]'); +go + +SELECT cosine_distance('[1,1]', '[-1,-1]'); +go + +SELECT cosine_distance('[1,2]', '[3]'); +go + +SELECT cosine_distance('[1,1]', '[1.1,1.1]'); +go + +SELECT cosine_distance('[1,1]', '[-1.1,-1.1]'); +go + +SELECT cosine_distance('[3e38]', '[3e38]'); +go + +SELECT l1_distance('[0,0]', '[3,4]'); +go + +SELECT l1_distance('[0,0]', '[0,1]'); +go + +SELECT l1_distance('[1,2]', '[3]'); +go + +SELECT l1_distance('[3e38]', '[-3e38]'); +go + +SELECT vector_avg(array_agg(n)) FROM generate_series(1, 16002) n; +go + +-- cast. has all arrays can prune maybe use array_to_vector + +SELECT CAST(CAST('{NULL}' as real[]) as vector); +go + +SELECT CAST(CAST('{NaN}' as real[]) as vector); +go + +SELECT CAST(CAST('{Infinity}' as real[]) as vector); +go + +SELECT CAST(array_agg(n) as vector) FROM generate_series(1, 1600) n; +go + +SELECT CAST(array_agg(n) as vector) FROM generate_series(1, 16001) n; +go + +SELECT array_to_vector(array_agg(n), 1600, false) FROM generate_series(1, 1600) n +go + +SELECT array_to_vector(array_agg(n), 16001, false) FROM generate_series(1, 16001) n; +go + +-- btree +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go + +CREATE INDEX idx ON vector_table (val); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go + +SELECT * FROM vector_table WHERE val = '[1,2,3]'; +go + +SELECT TOP 1 * FROM vector_table ORDER BY val; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go + +-- hnsw_cosine +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go + +CREATE INDEX idx ON vector_table USING hnsw (val vector_cosine_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go + +SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]'; +go + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]') t2; +go +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go + +-- hnsw_ip +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go + +CREATE INDEX idx ON vector_table USING hnsw (val vector_ip_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go + +SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]'; +go + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]') t2; +go +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go + +-- hnsw_l2 +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go + +CREATE INDEX idx ON vector_table USING hnsw (val vector_l2_ops); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go + +SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]'; +go + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]') t2; +go +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go + +-- hnsw options +CREATE TABLE vector_table (val vector(3)); +go + +CREATE INDEX idx1 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 1); +go + +CREATE INDEX idx2 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 101); +go + +CREATE INDEX idx3 ON vector_table USING hnsw (val vector_l2_ops) WITH (ef_construction = 3); +go + +CREATE INDEX idx4 ON vector_table USING hnsw (val vector_l2_ops) WITH (ef_construction = 1001); +go + +CREATE INDEX idx5 ON vector_table USING hnsw (val vector_l2_ops) WITH (m = 16, ef_construction = 31); +go + +Select current_setting('hnsw.ef_search') +go + +SELECT set_config('hnsw.ef_search', '0', false) +go + +SELECT set_config('hnsw.ef_search', '1001', false) +go + +DROP TABLE vector_table; +go + +-- ivfflat cosine +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go + +CREATE INDEX idx ON vector_table USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go + +SELECT * FROM vector_table ORDER BY val <=> '[3,3,3]'; +go + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> '[0,0,0]') t2; +go + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <=> (SELECT CAST(NULL as vector))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go + +-- ivfflat ip +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go + +CREATE INDEX idx2 ON vector_table USING ivfflat (val vector_ip_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go + +SELECT * FROM vector_table ORDER BY val <#> '[3,3,3]'; +go + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> '[0,0,0]') t2; +go + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <#> (SELECT CAST(NULL as vector))) t2; +go + + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go + +-- ivfflat l2 +CREATE TABLE vector_table (val vector(3)); +go + +INSERT INTO vector_table (val) VALUES ('[0,0,0]'), ('[1,2,3]'), ('[1,1,1]'), (NULL); +go + +CREATE INDEX idx ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 1); +go + +INSERT INTO vector_table (val) VALUES ('[1,2,4]'); +go + +-- test explain output for index scan +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go +SELECT * FROM vector_table ORDER BY val <-> '[3,3,3]'; +go + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> '[0,0,0]') t2; +go + +SELECT COUNT(*) FROM (SELECT * FROM vector_table ORDER BY val <-> (SELECT CAST(NULL as vector))) t2; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +DROP TABLE vector_table; +go + +-- ivfflat options + +CREATE TABLE vector_table (val vector(3)); +go + +CREATE INDEX idx1 ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 0); +go + +CREATE INDEX idx2 ON vector_table USING ivfflat (val vector_l2_ops) WITH (lists = 32769); +go + +Select current_setting('ivfflat.probes') +go + +DROP TABLE vector_table; +go + +-- input +SELECT CAST('[1,2,3]' as vector); +go + +SELECT CAST('[-1,-2,-3]' as vector); +go + +SELECT CAST('[1.,2.,3.]' as vector); +go + +SELECT CAST(' [ 1, 2 , 3 ] ' as vector); +go + +SELECT CAST('[1.23456]' as vector); +go + +SELECT CAST('[hello,1]' as vector); +go + +SELECT CAST('[NaN,1]' as vector); +go + +SELECT CAST('[Infinity,1]' as vector); +go + +SELECT CAST('[-Infinity,1]' as vector); +go + +SELECT CAST('[1.5e38,-1.5e38]' as vector); +go + +SELECT CAST('[1.5e+38,-1.5e+38]' as vector); +go + +SELECT CAST('[1.5e-38,-1.5e-38]' as vector); +go + +SELECT CAST('[4e38,1]' as vector); +go + +SELECT CAST('[1,2,3' as vector); +go + +SELECT CAST('[1,2,3]9' as vector); +go + +SELECT CAST('1,2,3' as vector); +go + +SELECT CAST('' as vector); +go + +SELECT CAST('[' as vector); +go + +SELECT CAST('[,' as vector); +go + +SELECT CAST('[]' as vector); +go + +SELECT CAST('[1,]' as vector); +go + +SELECT CAST('[1a]' as vector); +go + +SELECT CAST('[1,,3]' as vector); +go + +SELECT CAST('[1, ,3]' as vector); +go + +SELECT CAST('[1,2,3]' as vector(2)); +go + +-- cummulative order by index/seq scan tests +CREATE TABLE vector_table1 (a int, val vector(3)); +go + +CREATE TABLE vector_table2 (a int, val vector(3)); +go + +CREATE TABLE table3 (a int, b int); +go + +INSERT INTO vector_table1 VALUES (1, '[0,0,0]'), (3, '[1,2,3]'),(NULL, NULL), (2, '[1,1,1]'); +INSERT INTO vector_table2 VALUES (1, '[0,0,0]'), (3, '[1,2,3]'),(NULL, NULL), (2, '[1,1,1]'); +INSERT INTO table3 (1, 3), (3, 5), (NULL, NULL), (2, 4); +go + +CREATE INDEX idx ON vector_table1 USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +CREATE INDEX idx ON vector_table2 USING ivfflat (val vector_cosine_ops) WITH (lists = 1); +go + +SET BABELFISH_STATISTICS PROFILE ON; SELECT set_config('enable_seqscan', 'off', false); +go + +SELECT * FROM vector_table1 ORDER BY val <=> '[3,3,3]'; +go + +-- single column order, should use index scan thus NULLS LAST +SELECT t1.*, t2.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]'; +go + +-- more than one column order, should use seq scan NULLS FIRST +SELECT t1.* FROM vector_table1 as t1 JOIN vector_table2 as t2 ON t1.a = t2.a ORDER BY t1.val <=> '[0,0,0]', t2.val <=> '[1,1,1]'; +go + +SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]'; +go + +SELECT t1.* FROM vector_table1 as t1 JOIN table3 as t2 ON t1.a = t2.a ORDER BY val <=> '[0,0,0]', t2.a; +go + +SET BABELFISH_STATISTICS PROFILE OFF; SELECT set_config('enable_seqscan', 'on', false); +go + +DROP TABLE vector_table1; +DROP TABLE vector_table2; +DROP TABLE table3; +go + +select set_config('babelfishpg_tsql.explain_costs', 'on', false); +go +select set_config('babelfishpg_tsql.explain_timing', 'on', false); +go +select set_config('babelfishpg_tsql.explain_summary', 'on', false); +go + +-- system metadata, all objects get their datatype info from one of: +-- typecodes or datatype_info data we have created. Testing sys.types for typecodes +-- and sp_sproc_columns_100 for datatype_info is enough +select count(*) from sys.types where name = 'vector'; +go + +create procedure vector_proc_1 @a vector, @b varchar(max) as select @a as a, @b as b; +go + +exec sp_sproc_columns_100 @procedure_name= 'vector_proc_1' +go + +drop procedure vector_proc_1; +go + +create table t(a vector(3), b varchar(max)) +go +select * from information_schema.columns where table_name = 't' +go +select count(*) from sys.columns where object_id = sys.object_id('t') +go +drop table t; +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'vector_login' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +GO + +-- tsql +use master +go + +exec sp_execute_postgresql 'drop extension vector'; +go + +drop login vector_login +go + +drop database vector_db; +go \ No newline at end of file