From e5a1830c021cce612e02e8495a12068fb59fcef3 Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Wed, 19 Jul 2023 11:37:37 +0530 Subject: [PATCH 1/8] changes --- google/cloud/spanner_v1/database.py | 2 +- google/cloud/spanner_v1/snapshot.py | 4 ++-- google/cloud/spanner_v1/transaction.py | 5 ---- setup.py | 32 +++++++++++++++++++++++++- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/google/cloud/spanner_v1/database.py b/google/cloud/spanner_v1/database.py index 9df479519f..62bd823a26 100644 --- a/google/cloud/spanner_v1/database.py +++ b/google/cloud/spanner_v1/database.py @@ -629,7 +629,7 @@ def execute_partitioned_dml( from google.cloud.spanner_v1.transaction import Transaction if param_types is None: - raise ValueError("Specify 'param_types' when passing 'params'.") + param_types = {} params_pb = Transaction._make_params_pb(params, param_types) else: params_pb = {} diff --git a/google/cloud/spanner_v1/snapshot.py b/google/cloud/spanner_v1/snapshot.py index 6d17bfc386..9faeb9c336 100644 --- a/google/cloud/spanner_v1/snapshot.py +++ b/google/cloud/spanner_v1/snapshot.py @@ -391,7 +391,7 @@ def execute_sql( if params is not None: if param_types is None: - raise ValueError("Specify 'param_types' when passing 'params'.") + param_types = {} params_pb = Struct( fields={key: _make_value_pb(value) for key, value in params.items()} ) @@ -633,7 +633,7 @@ def partition_query( if params is not None: if param_types is None: - raise ValueError("Specify 'param_types' when passing 'params'.") + param_types = {} params_pb = Struct( fields={key: _make_value_pb(value) for (key, value) in params.items()} ) diff --git a/google/cloud/spanner_v1/transaction.py b/google/cloud/spanner_v1/transaction.py index dee99a0c6f..6afda76ba3 100644 --- a/google/cloud/spanner_v1/transaction.py +++ b/google/cloud/spanner_v1/transaction.py @@ -267,14 +267,9 @@ def _make_params_pb(params, param_types): If ``params`` is None but ``param_types`` is not None. """ if params is not None: - if param_types is None: - raise ValueError("Specify 'param_types' when passing 'params'.") return Struct( fields={key: _make_value_pb(value) for key, value in params.items()} ) - else: - if param_types is not None: - raise ValueError("Specify 'params' when passing 'param_types'.") return {} diff --git a/setup.py b/setup.py index 7f72131638..98cfcb1185 100644 --- a/setup.py +++ b/setup.py @@ -69,7 +69,37 @@ namespaces = ["google"] if "google.cloud" in packages: namespaces.append("google.cloud") - +print( + [name, + version, + description, + readme, + "Google LLC", + "googleapis-packages@google.com", + "Apache 2.0", + url, + [ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + "Posix; MacOS X; Windows", + packages, + namespaces, + dependencies, + extras, + ">=3.7", + True, + False] +) setuptools.setup( name=name, version=version, From bd346dac789d4beae6b9448c7880528452156186 Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Wed, 16 Aug 2023 11:42:19 +0530 Subject: [PATCH 2/8] change --- setup.py | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/setup.py b/setup.py index 98cfcb1185..9dd68c63d6 100644 --- a/setup.py +++ b/setup.py @@ -69,37 +69,6 @@ namespaces = ["google"] if "google.cloud" in packages: namespaces.append("google.cloud") -print( - [name, - version, - description, - readme, - "Google LLC", - "googleapis-packages@google.com", - "Apache 2.0", - url, - [ - release_status, - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Operating System :: OS Independent", - "Topic :: Internet", - ], - "Posix; MacOS X; Windows", - packages, - namespaces, - dependencies, - extras, - ">=3.7", - True, - False] -) setuptools.setup( name=name, version=version, From 82aa5cadbb452315795f4812cf2743382ce9ceff Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Thu, 17 Aug 2023 15:27:50 +0530 Subject: [PATCH 3/8] tests --- google/cloud/spanner_v1/snapshot.py | 4 ---- setup.py | 1 + tests/system/test_session_api.py | 25 +++++++++++++++++++++++-- tests/unit/test_database.py | 4 ---- tests/unit/test_snapshot.py | 22 ---------------------- tests/unit/test_transaction.py | 24 ------------------------ 6 files changed, 24 insertions(+), 56 deletions(-) diff --git a/google/cloud/spanner_v1/snapshot.py b/google/cloud/spanner_v1/snapshot.py index f097bc1d8b..6fb7156e5e 100644 --- a/google/cloud/spanner_v1/snapshot.py +++ b/google/cloud/spanner_v1/snapshot.py @@ -390,8 +390,6 @@ def execute_sql( raise ValueError("Transaction ID pending.") if params is not None: - if param_types is None: - param_types = {} params_pb = Struct( fields={key: _make_value_pb(value) for key, value in params.items()} ) @@ -632,8 +630,6 @@ def partition_query( raise ValueError("Transaction not started.") if params is not None: - if param_types is None: - param_types = {} params_pb = Struct( fields={key: _make_value_pb(value) for (key, value) in params.items()} ) diff --git a/setup.py b/setup.py index 9dd68c63d6..7f72131638 100644 --- a/setup.py +++ b/setup.py @@ -69,6 +69,7 @@ namespaces = ["google"] if "google.cloud" in packages: namespaces.append("google.cloud") + setuptools.setup( name=name, version=version, diff --git a/tests/system/test_session_api.py b/tests/system/test_session_api.py index 7d58324b04..1260490aef 100644 --- a/tests/system/test_session_api.py +++ b/tests/system/test_session_api.py @@ -1922,8 +1922,8 @@ def _check_sql_results( database, sql, params, - param_types, - expected, + param_types=None, + expected=None, order=True, recurse_into_lists=True, ): @@ -2027,6 +2027,7 @@ def _bind_test_helper( array_value, expected_array_value=None, recurse_into_lists=True, + test_untyped_param=False, ): database.snapshot(multi_use=True) @@ -2096,6 +2097,17 @@ def _bind_test_helper( recurse_into_lists=recurse_into_lists, ) + # Bind without paramtype of + if test_untyped_param: + _check_sql_results( + database, + sql=f"SELECT {placeholder}", + params={key: single_value}, + expected=[(single_value,)], + order=False, + recurse_into_lists=recurse_into_lists, + ) + def test_execute_sql_w_string_bindings(sessions_database, database_dialect): _bind_test_helper( @@ -2104,6 +2116,7 @@ def test_execute_sql_w_string_bindings(sessions_database, database_dialect): spanner_v1.param_types.STRING, "Phred", ["Phred", "Bharney"], + test_untyped_param=True, ) @@ -2114,6 +2127,7 @@ def test_execute_sql_w_bool_bindings(sessions_database, database_dialect): spanner_v1.param_types.BOOL, True, [True, False, True], + test_untyped_param=True, ) @@ -2124,6 +2138,7 @@ def test_execute_sql_w_int64_bindings(sessions_database, database_dialect): spanner_v1.param_types.INT64, 42, [123, 456, 789], + test_untyped_param=True, ) @@ -2134,6 +2149,7 @@ def test_execute_sql_w_float64_bindings(sessions_database, database_dialect): spanner_v1.param_types.FLOAT64, 42.3, [12.3, 456.0, 7.89], + test_untyped_param=True, ) @@ -2171,6 +2187,7 @@ def test_execute_sql_w_bytes_bindings(sessions_database, database_dialect): spanner_v1.param_types.BYTES, b"DEADBEEF", [b"FACEDACE", b"DEADBEEF"], + test_untyped_param=True, ) @@ -2197,6 +2214,7 @@ def test_execute_sql_w_timestamp_bindings(sessions_database, database_dialect): timestamps, expected_timestamps, recurse_into_lists=False, + test_untyped_param=True, ) @@ -2208,6 +2226,7 @@ def test_execute_sql_w_date_bindings(sessions_database, not_postgres, database_d spanner_v1.param_types.DATE, SOME_DATE, dates, + test_untyped_param=True, ) @@ -2221,6 +2240,7 @@ def test_execute_sql_w_numeric_bindings( spanner_v1.param_types.PG_NUMERIC, NUMERIC_1, [NUMERIC_1, NUMERIC_2], + test_untyped_param=True, ) else: _bind_test_helper( @@ -2229,6 +2249,7 @@ def test_execute_sql_w_numeric_bindings( spanner_v1.param_types.NUMERIC, NUMERIC_1, [NUMERIC_1, NUMERIC_2], + test_untyped_param=True, ) diff --git a/tests/unit/test_database.py b/tests/unit/test_database.py index 5a6abf8084..04ab21350e 100644 --- a/tests/unit/test_database.py +++ b/tests/unit/test_database.py @@ -1116,10 +1116,6 @@ def _execute_partitioned_dml_helper( def test_execute_partitioned_dml_wo_params(self): self._execute_partitioned_dml_helper(dml=DML_WO_PARAM) - def test_execute_partitioned_dml_w_params_wo_param_types(self): - with self.assertRaises(ValueError): - self._execute_partitioned_dml_helper(dml=DML_W_PARAM, params=PARAMS) - def test_execute_partitioned_dml_w_params_and_param_types(self): self._execute_partitioned_dml_helper( dml=DML_W_PARAM, params=PARAMS, param_types=PARAM_TYPES diff --git a/tests/unit/test_snapshot.py b/tests/unit/test_snapshot.py index 5d2afb4fe6..ebb1acb6bf 100644 --- a/tests/unit/test_snapshot.py +++ b/tests/unit/test_snapshot.py @@ -815,16 +815,6 @@ def test_execute_sql_other_error(self): attributes=dict(BASE_ATTRIBUTES, **{"db.statement": SQL_QUERY}), ) - def test_execute_sql_w_params_wo_param_types(self): - database = _Database() - session = _Session(database) - derived = self._makeDerived(session) - - with self.assertRaises(ValueError): - derived.execute_sql(SQL_QUERY_WITH_PARAM, PARAMS) - - self.assertNoSpans() - def _execute_sql_helper( self, multi_use, @@ -1314,18 +1304,6 @@ def test_partition_query_other_error(self): attributes=dict(BASE_ATTRIBUTES, **{"db.statement": SQL_QUERY}), ) - def test_partition_query_w_params_wo_param_types(self): - database = _Database() - session = _Session(database) - derived = self._makeDerived(session) - derived._multi_use = True - derived._transaction_id = TXN_ID - - with self.assertRaises(ValueError): - list(derived.partition_query(SQL_QUERY_WITH_PARAM, PARAMS)) - - self.assertNoSpans() - def test_partition_query_single_use_raises(self): with self.assertRaises(ValueError): self._partition_query_helper(multi_use=False, w_txn=True) diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index 85359dac19..7a3b66a183 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -452,20 +452,6 @@ def test_commit_w_incorrect_tag_dictionary_error(self): with self.assertRaises(ValueError): self._commit_helper(request_options=request_options) - def test__make_params_pb_w_params_wo_param_types(self): - session = _Session() - transaction = self._make_one(session) - - with self.assertRaises(ValueError): - transaction._make_params_pb(PARAMS, None) - - def test__make_params_pb_wo_params_w_param_types(self): - session = _Session() - transaction = self._make_one(session) - - with self.assertRaises(ValueError): - transaction._make_params_pb(None, PARAM_TYPES) - def test__make_params_pb_w_params_w_param_types(self): from google.protobuf.struct_pb2 import Struct from google.cloud.spanner_v1._helpers import _make_value_pb @@ -491,16 +477,6 @@ def test_execute_update_other_error(self): with self.assertRaises(RuntimeError): transaction.execute_update(DML_QUERY) - def test_execute_update_w_params_wo_param_types(self): - database = _Database() - database.spanner_api = self._make_spanner_api() - session = _Session(database) - transaction = self._make_one(session) - transaction._transaction_id = self.TRANSACTION_ID - - with self.assertRaises(ValueError): - transaction.execute_update(DML_QUERY_WITH_PARAM, PARAMS) - def _execute_update_helper( self, count=0, From e01d9b4f6ab8f63a85ff85f1aa8949b167b24021 Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Thu, 17 Aug 2023 16:21:45 +0530 Subject: [PATCH 4/8] tests --- tests/system/test_session_api.py | 50 ++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/tests/system/test_session_api.py b/tests/system/test_session_api.py index 1260490aef..d8187585c9 100644 --- a/tests/system/test_session_api.py +++ b/tests/system/test_session_api.py @@ -90,6 +90,8 @@ "jsonb_array", ) +QUERY_ALL_TYPES_COLUMNS = LIVE_ALL_TYPES_COLUMNS[1:17:2] + AllTypesRowData = collections.namedtuple("AllTypesRowData", LIVE_ALL_TYPES_COLUMNS) AllTypesRowData.__new__.__defaults__ = tuple([None for colum in LIVE_ALL_TYPES_COLUMNS]) EmulatorAllTypesRowData = collections.namedtuple( @@ -211,6 +213,17 @@ PostGresAllTypesRowData(pkey=309, jsonb_array=[JSON_1, JSON_2, None]), ) +QUERY_ALL_TYPES_DATA = ( + 123, + False, + BYTES_1, + SOME_DATE, + 1.4142136, + "VALUE", + SOME_TIME, + NUMERIC_1, +) + if _helpers.USE_EMULATOR: ALL_TYPES_COLUMNS = EMULATOR_ALL_TYPES_COLUMNS ALL_TYPES_ROWDATA = EMULATOR_ALL_TYPES_ROWDATA @@ -476,6 +489,22 @@ def test_batch_insert_or_update_then_query(sessions_database): sd._check_rows_data(rows) +def test_batch_insert_then_read_wo_param_types(sessions_database, database_dialect, not_emulator): + sd = _sample_data + + with sessions_database.batch() as batch: + batch.delete(ALL_TYPES_TABLE, sd.ALL) + batch.insert(ALL_TYPES_TABLE, ALL_TYPES_COLUMNS, ALL_TYPES_ROWDATA) + + with sessions_database.snapshot(multi_use=True) as snapshot: + for column_type, value in list(zip(QUERY_ALL_TYPES_COLUMNS, QUERY_ALL_TYPES_DATA)): + placeholder = "$1" if database_dialect == DatabaseDialect.POSTGRESQL else f"@value" + sql = 'SELECT * FROM `' + ALL_TYPES_TABLE + '` WHERE ' + column_type + ' = ' + placeholder + param = {"p1": value} if database_dialect == DatabaseDialect.POSTGRESQL else {"value": value} + rows = list(snapshot.execute_sql(sql,params=param)) + assert len(rows) == 1 + + def test_batch_insert_w_commit_timestamp(sessions_database, not_postgres): table = "users_history" columns = ["id", "commit_ts", "name", "email", "deleted"] @@ -2027,7 +2056,6 @@ def _bind_test_helper( array_value, expected_array_value=None, recurse_into_lists=True, - test_untyped_param=False, ): database.snapshot(multi_use=True) @@ -2097,17 +2125,6 @@ def _bind_test_helper( recurse_into_lists=recurse_into_lists, ) - # Bind without paramtype of - if test_untyped_param: - _check_sql_results( - database, - sql=f"SELECT {placeholder}", - params={key: single_value}, - expected=[(single_value,)], - order=False, - recurse_into_lists=recurse_into_lists, - ) - def test_execute_sql_w_string_bindings(sessions_database, database_dialect): _bind_test_helper( @@ -2116,7 +2133,6 @@ def test_execute_sql_w_string_bindings(sessions_database, database_dialect): spanner_v1.param_types.STRING, "Phred", ["Phred", "Bharney"], - test_untyped_param=True, ) @@ -2127,7 +2143,6 @@ def test_execute_sql_w_bool_bindings(sessions_database, database_dialect): spanner_v1.param_types.BOOL, True, [True, False, True], - test_untyped_param=True, ) @@ -2138,7 +2153,6 @@ def test_execute_sql_w_int64_bindings(sessions_database, database_dialect): spanner_v1.param_types.INT64, 42, [123, 456, 789], - test_untyped_param=True, ) @@ -2149,7 +2163,6 @@ def test_execute_sql_w_float64_bindings(sessions_database, database_dialect): spanner_v1.param_types.FLOAT64, 42.3, [12.3, 456.0, 7.89], - test_untyped_param=True, ) @@ -2187,7 +2200,6 @@ def test_execute_sql_w_bytes_bindings(sessions_database, database_dialect): spanner_v1.param_types.BYTES, b"DEADBEEF", [b"FACEDACE", b"DEADBEEF"], - test_untyped_param=True, ) @@ -2214,7 +2226,6 @@ def test_execute_sql_w_timestamp_bindings(sessions_database, database_dialect): timestamps, expected_timestamps, recurse_into_lists=False, - test_untyped_param=True, ) @@ -2226,7 +2237,6 @@ def test_execute_sql_w_date_bindings(sessions_database, not_postgres, database_d spanner_v1.param_types.DATE, SOME_DATE, dates, - test_untyped_param=True, ) @@ -2240,7 +2250,6 @@ def test_execute_sql_w_numeric_bindings( spanner_v1.param_types.PG_NUMERIC, NUMERIC_1, [NUMERIC_1, NUMERIC_2], - test_untyped_param=True, ) else: _bind_test_helper( @@ -2249,7 +2258,6 @@ def test_execute_sql_w_numeric_bindings( spanner_v1.param_types.NUMERIC, NUMERIC_1, [NUMERIC_1, NUMERIC_2], - test_untyped_param=True, ) From 9f8a92d8a29c1cf54bc46e1ba3a7cb9071938e6b Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Thu, 17 Aug 2023 16:47:41 +0530 Subject: [PATCH 5/8] changes --- tests/system/test_session_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/test_session_api.py b/tests/system/test_session_api.py index d8187585c9..7ac9f42bdf 100644 --- a/tests/system/test_session_api.py +++ b/tests/system/test_session_api.py @@ -499,7 +499,7 @@ def test_batch_insert_then_read_wo_param_types(sessions_database, database_diale with sessions_database.snapshot(multi_use=True) as snapshot: for column_type, value in list(zip(QUERY_ALL_TYPES_COLUMNS, QUERY_ALL_TYPES_DATA)): placeholder = "$1" if database_dialect == DatabaseDialect.POSTGRESQL else f"@value" - sql = 'SELECT * FROM `' + ALL_TYPES_TABLE + '` WHERE ' + column_type + ' = ' + placeholder + sql = 'SELECT * FROM ' + ALL_TYPES_TABLE + ' WHERE ' + column_type + ' = ' + placeholder param = {"p1": value} if database_dialect == DatabaseDialect.POSTGRESQL else {"value": value} rows = list(snapshot.execute_sql(sql,params=param)) assert len(rows) == 1 From d9040e984603d6216c1eee1efa780a010bea866e Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Thu, 17 Aug 2023 16:51:14 +0530 Subject: [PATCH 6/8] change --- google/cloud/spanner_v1/database.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/google/cloud/spanner_v1/database.py b/google/cloud/spanner_v1/database.py index 446ba73955..68bc24f390 100644 --- a/google/cloud/spanner_v1/database.py +++ b/google/cloud/spanner_v1/database.py @@ -627,9 +627,6 @@ def execute_partitioned_dml( if params is not None: from google.cloud.spanner_v1.transaction import Transaction - - if param_types is None: - param_types = {} params_pb = Transaction._make_params_pb(params, param_types) else: params_pb = {} From 6a689fade593fc9e75c33845f423efa037e04ad2 Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Thu, 17 Aug 2023 16:51:59 +0530 Subject: [PATCH 7/8] lint --- google/cloud/spanner_v1/database.py | 1 + tests/system/test_session_api.py | 29 +++++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/google/cloud/spanner_v1/database.py b/google/cloud/spanner_v1/database.py index 68bc24f390..790dedf39b 100644 --- a/google/cloud/spanner_v1/database.py +++ b/google/cloud/spanner_v1/database.py @@ -627,6 +627,7 @@ def execute_partitioned_dml( if params is not None: from google.cloud.spanner_v1.transaction import Transaction + params_pb = Transaction._make_params_pb(params, param_types) else: params_pb = {} diff --git a/tests/system/test_session_api.py b/tests/system/test_session_api.py index 7ac9f42bdf..c61f9efc7b 100644 --- a/tests/system/test_session_api.py +++ b/tests/system/test_session_api.py @@ -489,7 +489,9 @@ def test_batch_insert_or_update_then_query(sessions_database): sd._check_rows_data(rows) -def test_batch_insert_then_read_wo_param_types(sessions_database, database_dialect, not_emulator): +def test_batch_insert_then_read_wo_param_types( + sessions_database, database_dialect, not_emulator +): sd = _sample_data with sessions_database.batch() as batch: @@ -497,11 +499,26 @@ def test_batch_insert_then_read_wo_param_types(sessions_database, database_diale batch.insert(ALL_TYPES_TABLE, ALL_TYPES_COLUMNS, ALL_TYPES_ROWDATA) with sessions_database.snapshot(multi_use=True) as snapshot: - for column_type, value in list(zip(QUERY_ALL_TYPES_COLUMNS, QUERY_ALL_TYPES_DATA)): - placeholder = "$1" if database_dialect == DatabaseDialect.POSTGRESQL else f"@value" - sql = 'SELECT * FROM ' + ALL_TYPES_TABLE + ' WHERE ' + column_type + ' = ' + placeholder - param = {"p1": value} if database_dialect == DatabaseDialect.POSTGRESQL else {"value": value} - rows = list(snapshot.execute_sql(sql,params=param)) + for column_type, value in list( + zip(QUERY_ALL_TYPES_COLUMNS, QUERY_ALL_TYPES_DATA) + ): + placeholder = ( + "$1" if database_dialect == DatabaseDialect.POSTGRESQL else f"@value" + ) + sql = ( + "SELECT * FROM " + + ALL_TYPES_TABLE + + " WHERE " + + column_type + + " = " + + placeholder + ) + param = ( + {"p1": value} + if database_dialect == DatabaseDialect.POSTGRESQL + else {"value": value} + ) + rows = list(snapshot.execute_sql(sql, params=param)) assert len(rows) == 1 From d2b84da0696dc3d161f5d0234e3961ada902b1f0 Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Thu, 17 Aug 2023 17:14:48 +0530 Subject: [PATCH 8/8] lint --- tests/system/test_session_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/test_session_api.py b/tests/system/test_session_api.py index c61f9efc7b..61991a7d5c 100644 --- a/tests/system/test_session_api.py +++ b/tests/system/test_session_api.py @@ -503,7 +503,7 @@ def test_batch_insert_then_read_wo_param_types( zip(QUERY_ALL_TYPES_COLUMNS, QUERY_ALL_TYPES_DATA) ): placeholder = ( - "$1" if database_dialect == DatabaseDialect.POSTGRESQL else f"@value" + "$1" if database_dialect == DatabaseDialect.POSTGRESQL else "@value" ) sql = ( "SELECT * FROM "