From ee07536f5e10724b1b16a5a810d6a450e875095f Mon Sep 17 00:00:00 2001 From: Lynn Date: Sat, 21 Oct 2023 16:59:38 -0700 Subject: [PATCH] insert into WIP --- data/sql_input_2.sql | 21 +++++++++++ data/sql_output_2.json | 5 +++ src/python/sql_test.py | 81 ++++++++++++++++++++++++++++++++---------- 3 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 data/sql_input_2.sql create mode 100644 data/sql_output_2.json diff --git a/data/sql_input_2.sql b/data/sql_input_2.sql new file mode 100644 index 0000000..89b50fb --- /dev/null +++ b/data/sql_input_2.sql @@ -0,0 +1,21 @@ +-- https://cratedb.com/docs/sql-99/en/latest/chapters/01.html +-- https://www.postgresql.org/docs/16/sql-createtable.html +-- https://www.postgresql.org/docs/16/sql-insert.html +-- https://www.postgresql.org/docs/16/sql-select.html +CREATE TABLE city ( + name VARCHAR, + population INT, + timezone INT +); + +INSERT INTO city (name, population, timezone) +VALUES ('San Francisco', 852469, -8); + +INSERT INTO city (name, population, timezone) +VALUES ('New York', 8405837, -5); + +SELECT + name, + population, + timezone +FROM city; diff --git a/data/sql_output_2.json b/data/sql_output_2.json new file mode 100644 index 0000000..da4110b --- /dev/null +++ b/data/sql_output_2.json @@ -0,0 +1,5 @@ +{ + "name": ["San Francisco", "New York"], + "population": [852469, 8405837], + "timezone": [-8, -5] +} diff --git a/src/python/sql_test.py b/src/python/sql_test.py index 7f41e13..6297404 100644 --- a/src/python/sql_test.py +++ b/src/python/sql_test.py @@ -13,27 +13,61 @@ class SQL: - data: dict = {} + __data: dict = {} def __init__(self) -> None: - self.data = {} + self.clear_data() - def information_schema_tables(self) -> list[dict]: - return [data["metadata"] for data in self.data.values()] + def clear_data(self): + self.__data = {} + + def read_data_table(self, table_name: str) -> dict: + return self.__data.get(table_name, {}) + + def read_information_schema_tables(self) -> list[dict]: + return [data["metadata"] for data in self.__data.values()] + + def write_table_meta(self, table_name: str, data: dict): + self.__data[table_name] = data + + def write_table_data(self, table_name: str, data: dict): + self.__data[table_name]["data"] = data def create_table(self, *args, table_schema="public") -> dict: table_name = args[2] - if not self.data.get(table_name): - self.data[table_name] = { - "metadata": { - "table_name": table_name, - "table_schema": table_schema, - }, + + # get columns + columns = {} + columns_str = " ".join(args[3:]).replace("(", "").replace(")", "").strip() + if columns_str: + # fmt: off + columns = { + column.strip().split(" ")[0]: column.strip().split(" ")[1] + for column in columns_str.split(",") } + # fmt: on + + if self.read_data_table(table_name): + self.write_table_meta( + table_name, + { + "metadata": { + "table_name": table_name, + "table_schema": table_schema, + "colums": columns, + } + }, + ) return {} create_table.sql = "CREATE TABLE" + def insert_into(self, *args) -> dict: + print(f"args: {args}") + pass + + insert_into.sql = "INSERT INTO" + def select(self, *args) -> dict: output = {} @@ -54,7 +88,9 @@ def select(self, *args) -> dict: # consider "information_schema.tables" a special case until # we figure out why its so different from the others if from_value == "information_schema.tables": - target = self.information_schema_tables() + target = self.read_information_schema_tables() + else: + target = self.read_data_table(from_value) # fmt: off output = { @@ -74,19 +110,28 @@ def select(self, *args) -> dict: sql_map = { create_table.sql: create_table, select.sql: select, + insert_into.sql: insert_into, } def run(self, input_sql: list[str]) -> list[str]: output = {} + # remove comments + input_sql = [line.strip() for line in input_sql if not line.startswith("--")] + + # re-split on semi-colons + input_sql = " ".join(input_sql).split(";") + + # iterate over each line of sql for line in input_sql: - if not line.startswith("--"): - words = line.split(" ") - for i in reversed(range(len(words))): - key = " ".join(words[:i]) - if func := self.sql_map.get(key): - output = func(self, *words) - break + words = line.split(" ") + for i in reversed(range(len(words) + 1)): + key = " ".join(words[:i]).strip() + # print(f'key: "{key}"') + if func := self.sql_map.get(key): + # print(f'running "{func.__name__}" with {words}') + output = func(self, *[word for word in words if word]) + break return [json.dumps(output)]