From 0acf9c31dede8a3b92be54595aa34f70f24524fd Mon Sep 17 00:00:00 2001 From: John Gemignani Date: Tue, 25 Jul 2023 12:37:32 -0700 Subject: [PATCH 1/8] Temporary fix PR for CI jobs (#1089) Temporary fix for the CI jobs. For some strange reason, the DockerHub latest build is not working for CI connections. This is a temporary patch to allow them to run correctly while we look into the issue. --- .github/workflows/jdbc-driver.yaml | 4 ++-- drivers/docker-compose.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/jdbc-driver.yaml b/.github/workflows/jdbc-driver.yaml index 9be72f8cc..090c55503 100644 --- a/.github/workflows/jdbc-driver.yaml +++ b/.github/workflows/jdbc-driver.yaml @@ -27,13 +27,13 @@ jobs: run: | if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then if [[ "$GITHUB_REF" == "refs/heads/master" ]]; then - echo "TAG=latest" >> $GITHUB_ENV + echo "TAG=PG14_latest" >> $GITHUB_ENV elif [[ "$GITHUB_REF" == "refs/heads/PG14" ]]; then echo "TAG=PG14_latest" >> $GITHUB_ENV fi elif [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then if [[ "$GITHUB_BASE_REF" == "master" ]]; then - echo "TAG=latest" >> $GITHUB_ENV + echo "TAG=PG14_latest" >> $GITHUB_ENV elif [[ "$GITHUB_BASE_REF" == "PG14" ]]; then echo "TAG=PG14_latest" >> $GITHUB_ENV fi diff --git a/drivers/docker-compose.yml b/drivers/docker-compose.yml index 45ab86a39..095d72565 100644 --- a/drivers/docker-compose.yml +++ b/drivers/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.3" services: db: - image: apache/age:${TAG} + image: apache/age:PG14_latest environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=agens From 33095fa3385d8ed7f6a3920c77fb4c7fae7ab590 Mon Sep 17 00:00:00 2001 From: John Gemignani Date: Tue, 25 Jul 2023 15:15:02 -0700 Subject: [PATCH 2/8] Update files causing warning messages in DockerHub builds (#1095) Updated the following files which were generating warning messages in the DockerHub builds - modified: src/backend/parser/cypher_analyze.c modified: src/backend/parser/cypher_clause.c modified: src/backend/utils/adt/agtype.c modified: src/backend/utils/graph_generation.c Updated the following Docker file that has the wrong PostgreSQL version information - modified: docker/Dockerfile.dev --- docker/Dockerfile.dev | 2 +- src/backend/parser/cypher_analyze.c | 8 ++++ src/backend/parser/cypher_clause.c | 18 +++++++++ src/backend/utils/adt/agtype.c | 57 +++++++++++++++++++++++----- src/backend/utils/graph_generation.c | 2 +- 5 files changed, 75 insertions(+), 12 deletions(-) diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index 5e47d49b7..812aafd2a 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -17,7 +17,7 @@ # -FROM postgres:14-buster +FROM postgres:14 RUN apt-get update RUN apt-get install --assume-yes --no-install-recommends --no-install-suggests \ diff --git a/src/backend/parser/cypher_analyze.c b/src/backend/parser/cypher_analyze.c index f1c481c85..ea9a08893 100644 --- a/src/backend/parser/cypher_analyze.c +++ b/src/backend/parser/cypher_analyze.c @@ -756,8 +756,16 @@ static Query *analyze_cypher_and_coerce(List *stmt, RangeTblFunction *rtfunc, pnsi = addRangeTableEntryForSubquery(pstate, subquery, makeAlias("_", NIL), lateral, true); + rtindex = list_length(pstate->p_rtable); Assert(rtindex == 1); // rte is the only RangeTblEntry in pstate + if (rtindex !=1 ) + { + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("invalid value for rtindex"))); + } + addNSItemToQuery(pstate, pnsi, true, true, true); query->targetList = expandNSItemAttrs(pstate, pnsi, 0, -1); diff --git a/src/backend/parser/cypher_clause.c b/src/backend/parser/cypher_clause.c index cb1c48bf0..df1a4348c 100644 --- a/src/backend/parser/cypher_clause.c +++ b/src/backend/parser/cypher_clause.c @@ -2311,6 +2311,12 @@ static Query *transform_cypher_clause_with_where(cypher_parsestate *cpstate, Assert(pnsi != NULL); rtindex = list_length(pstate->p_rtable); Assert(rtindex == 1); // rte is the only RangeTblEntry in pstate + if (rtindex != 1) + { + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("invalid value for rtindex"))); + } /* * add all the target entries in pnsi to the current target list to pass @@ -2585,6 +2591,12 @@ static Query *transform_cypher_match_pattern(cypher_parsestate *cpstate, rte = pnsi->p_rte; rtindex = list_length(pstate->p_rtable); Assert(rtindex == 1); // rte is the first RangeTblEntry in pstate + if (rtindex != 1) + { + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("invalid value for rtindex"))); + } /* * add all the target entries in rte to the current target list to pass @@ -6775,6 +6787,12 @@ static void handle_prev_clause(cypher_parsestate *cpstate, Query *query, if (first_rte) { Assert(rtindex == 1); + if (rtindex != 1) + { + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("invalid value for rtindex"))); + } } // add all the rte's attributes to the current queries targetlist diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c index 376137aba..f60f85ee4 100644 --- a/src/backend/utils/adt/agtype.c +++ b/src/backend/utils/adt/agtype.c @@ -182,7 +182,7 @@ static int extract_variadic_args_min(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls, int min_num_args); -static agtype_value* agtype_build_map_as_agtype_value(FunctionCallInfo fcinfo); +static agtype_value *agtype_build_map_as_agtype_value(FunctionCallInfo fcinfo); agtype_value *agtype_composite_to_agtype_value_binary(agtype *a); /* global storage of OID for agtype and _agtype */ @@ -2364,7 +2364,7 @@ Datum make_edge(Datum id, Datum startid, Datum endid, Datum label, properties); } -static agtype_value* agtype_build_map_as_agtype_value(FunctionCallInfo fcinfo) +static agtype_value *agtype_build_map_as_agtype_value(FunctionCallInfo fcinfo) { int nargs; int i; @@ -2377,7 +2377,9 @@ static agtype_value* agtype_build_map_as_agtype_value(FunctionCallInfo fcinfo) nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls); if (nargs < 0) - PG_RETURN_NULL(); + { + return NULL; + } if (nargs % 2 != 0) { @@ -2420,7 +2422,14 @@ PG_FUNCTION_INFO_V1(agtype_build_map); */ Datum agtype_build_map(PG_FUNCTION_ARGS) { - agtype_value *result= agtype_build_map_as_agtype_value(fcinfo); + agtype_value *result = NULL; + + result = agtype_build_map_as_agtype_value(fcinfo); + if (result == NULL) + { + PG_RETURN_NULL(); + } + PG_RETURN_POINTER(agtype_value_to_agtype(result)); } @@ -2448,8 +2457,16 @@ PG_FUNCTION_INFO_V1(agtype_build_map_nonull); */ Datum agtype_build_map_nonull(PG_FUNCTION_ARGS) { - agtype_value *result= agtype_build_map_as_agtype_value(fcinfo); + agtype_value *result = NULL; + + result = agtype_build_map_as_agtype_value(fcinfo); + if (result == NULL) + { + PG_RETURN_NULL(); + } + remove_null_from_agtype_object(result); + PG_RETURN_POINTER(agtype_value_to_agtype(result)); } @@ -5446,18 +5463,26 @@ Datum age_tointeger(PG_FUNCTION_ARGS) if (type != AGTYPEOID) { if (type == INT2OID) + { result = (int64) DatumGetInt16(arg); + } else if (type == INT4OID) + { result = (int64) DatumGetInt32(arg); + } else if (type == INT8OID) + { result = (int64) DatumGetInt64(arg); + } else if (type == FLOAT4OID) { float4 f = DatumGetFloat4(arg); if (isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float4)PG_INT64_MIN || f > (float4)PG_INT64_MAX) + { PG_RETURN_NULL(); + } result = (int64) f; } @@ -5466,8 +5491,10 @@ Datum age_tointeger(PG_FUNCTION_ARGS) float8 f = DatumGetFloat8(arg); if (isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } result = (int64) f; } @@ -5479,17 +5506,23 @@ Datum age_tointeger(PG_FUNCTION_ARGS) numeric_float8_no_overflow, arg)); if (isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } result = (int64) f; } else if (type == CSTRINGOID || type == TEXTOID) { if (type == CSTRINGOID) + { string = DatumGetCString(arg); + } else + { string = text_to_cstring(DatumGetTextPP(arg)); + } /* convert it if it is a regular integer string */ is_valid = scanint8(string, true, &result); @@ -5499,7 +5532,7 @@ Datum age_tointeger(PG_FUNCTION_ARGS) */ if (!is_valid) { - float f; + float8 f; f = float8in_internal_null(string, NULL, "double precision", string, &is_valid); @@ -5508,16 +5541,20 @@ Datum age_tointeger(PG_FUNCTION_ARGS) * return null. */ if (!is_valid || isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } result = (int64) f; } } else + { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("toInteger() unsupported argument type %d", type))); + } } else { diff --git a/src/backend/utils/graph_generation.c b/src/backend/utils/graph_generation.c index 9b507e11a..0f58fbc36 100644 --- a/src/backend/utils/graph_generation.c +++ b/src/backend/utils/graph_generation.c @@ -83,7 +83,7 @@ Datum create_complete_graph(PG_FUNCTION_ARGS) int64 no_vertices; int64 i,j,vid = 1, eid, start_vid, end_vid; - Name vtx_label_name; + Name vtx_label_name = NULL; Name edge_label_name; int32 vtx_label_id; int32 edge_label_id; From 6059abeca321498d33478dc10934d7f2e1971ba0 Mon Sep 17 00:00:00 2001 From: John Gemignani Date: Tue, 25 Jul 2023 15:49:55 -0700 Subject: [PATCH 3/8] Update files causing warning messages in DockerHub builds part 2 (#1097) Updated the following files which were generating warning messages in the DockerHub builds - modified: src/backend/parser/cypher_clause.c modified: src/backend/utils/adt/agtype.c --- src/backend/parser/cypher_clause.c | 7 +++++++ src/backend/utils/adt/agtype.c | 20 +++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/backend/parser/cypher_clause.c b/src/backend/parser/cypher_clause.c index df1a4348c..299f12030 100644 --- a/src/backend/parser/cypher_clause.c +++ b/src/backend/parser/cypher_clause.c @@ -1334,6 +1334,13 @@ static Query *transform_cypher_unwind(cypher_parsestate *cpstate, pnsi = transform_prev_cypher_clause(cpstate, clause->prev, true); rtindex = list_length(pstate->p_rtable); Assert(rtindex == 1); // rte is the first RangeTblEntry in pstate + if (rtindex != 1) + { + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("invalid value for rtindex"))); + } + query->targetList = expandNSItemAttrs(pstate, pnsi, 0, -1); } diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c index f60f85ee4..c95419225 100644 --- a/src/backend/utils/adt/agtype.c +++ b/src/backend/utils/adt/agtype.c @@ -5574,11 +5574,13 @@ Datum age_tointeger(PG_FUNCTION_ARGS) result = agtv_value->val.int_value; else if (agtv_value->type == AGTV_FLOAT) { - float f = agtv_value->val.float_value; + float8 f = agtv_value->val.float_value; if (isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } result = (int64) f; } @@ -5591,8 +5593,10 @@ Datum age_tointeger(PG_FUNCTION_ARGS) numeric_float8_no_overflow, num)); if (isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } result = (int64) f; } @@ -5609,7 +5613,7 @@ Datum age_tointeger(PG_FUNCTION_ARGS) */ if (!is_valid) { - float f; + float8 f; f = float8in_internal_null(string, NULL, "double precision", string, &is_valid); @@ -5619,18 +5623,24 @@ Datum age_tointeger(PG_FUNCTION_ARGS) * return null. */ if (!is_valid || isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } result = (int64) f; } else + { free(string); + } } else + { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("toInteger() unsupported argument agtype %d", agtv_value->type))); + } } /* build the result */ From 5364a2a4af1e194c5c7234ec0f90e1522166f3a1 Mon Sep 17 00:00:00 2001 From: John Gemignani Date: Tue, 25 Jul 2023 16:46:59 -0700 Subject: [PATCH 4/8] Add installcheck to Dockerfile (#1098) Added the installcheck to the Dockerfile for debugging. --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index c30d69313..431cede73 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -26,7 +26,7 @@ RUN apt-get install --assume-yes --no-install-recommends --no-install-suggests \ postgresql-server-dev-14 COPY . /age -RUN cd /age && make install +RUN cd /age && make install && make installcheck COPY docker/docker-entrypoint-initdb.d/00-create-extension-age.sql /docker-entrypoint-initdb.d/00-create-extension-age.sql From 18456b3b2f58544b2920d3f39856ef74a9217536 Mon Sep 17 00:00:00 2001 From: John Gemignani Date: Tue, 25 Jul 2023 17:08:54 -0700 Subject: [PATCH 5/8] UNDO Dockerfile change (#1099) UNDO Dockerfile change to add installcheck. --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 431cede73..c30d69313 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -26,7 +26,7 @@ RUN apt-get install --assume-yes --no-install-recommends --no-install-suggests \ postgresql-server-dev-14 COPY . /age -RUN cd /age && make install && make installcheck +RUN cd /age && make install COPY docker/docker-entrypoint-initdb.d/00-create-extension-age.sql /docker-entrypoint-initdb.d/00-create-extension-age.sql From 7d05a8eb1c6995b4a8e6ad0439aff5666a9425df Mon Sep 17 00:00:00 2001 From: Muhammad Taha Naveed Date: Wed, 26 Jul 2023 06:58:23 +0500 Subject: [PATCH 6/8] Fix docker build files (#1104) This PR contains fix for dockerhub image. It will trigger a new build for latest tag when merged. --- docker/Dockerfile | 26 +++++++++++++++++++------- docker/Dockerfile.dev | 10 +++++++++- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index c30d69313..ac9803d5d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -18,15 +18,27 @@ FROM postgres:14 -RUN apt-get update -RUN apt-get install --assume-yes --no-install-recommends --no-install-suggests \ - bison \ - build-essential \ - flex \ - postgresql-server-dev-14 +RUN apt-get update \ + && apt-get install -y --no-install-recommends --no-install-suggests \ + bison \ + build-essential \ + flex \ + postgresql-server-dev-14 \ + locales + +ENV LANG=en_US.UTF-8 +ENV LC_COLLATE=en_US.UTF-8 +ENV LC_CTYPE=en_US.UTF-8 + +RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \ + && locale-gen \ + && update-locale LANG=en_US.UTF-8 COPY . /age -RUN cd /age && make install + +WORKDIR /age + +RUN make && make install COPY docker/docker-entrypoint-initdb.d/00-create-extension-age.sql /docker-entrypoint-initdb.d/00-create-extension-age.sql diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index 812aafd2a..8162f5b56 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -24,8 +24,16 @@ RUN apt-get install --assume-yes --no-install-recommends --no-install-suggests \ bison \ build-essential \ flex \ - postgresql-server-dev-14 + postgresql-server-dev-14 \ + locales +ENV LANG=en_US.UTF-8 +ENV LC_COLLATE=en_US.UTF-8 +ENV LC_CTYPE=en_US.UTF-8 + +RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \ + && locale-gen \ + && update-locale LANG=en_US.UTF-8 COPY . /age # Set current working directory to /age/ and build. From 20fcc1dfe28506c9db83d10e775e74354e006098 Mon Sep 17 00:00:00 2001 From: Muhammad Taha Naveed Date: Wed, 26 Jul 2023 07:42:49 +0500 Subject: [PATCH 7/8] Update CIs to pull correct image based on branch (#1105) - This commit/PR also serves as a test commit/PR for the newest image build of apache/age:latest --- .github/workflows/jdbc-driver.yaml | 4 ++-- drivers/docker-compose.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/jdbc-driver.yaml b/.github/workflows/jdbc-driver.yaml index 090c55503..9be72f8cc 100644 --- a/.github/workflows/jdbc-driver.yaml +++ b/.github/workflows/jdbc-driver.yaml @@ -27,13 +27,13 @@ jobs: run: | if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then if [[ "$GITHUB_REF" == "refs/heads/master" ]]; then - echo "TAG=PG14_latest" >> $GITHUB_ENV + echo "TAG=latest" >> $GITHUB_ENV elif [[ "$GITHUB_REF" == "refs/heads/PG14" ]]; then echo "TAG=PG14_latest" >> $GITHUB_ENV fi elif [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then if [[ "$GITHUB_BASE_REF" == "master" ]]; then - echo "TAG=PG14_latest" >> $GITHUB_ENV + echo "TAG=latest" >> $GITHUB_ENV elif [[ "$GITHUB_BASE_REF" == "PG14" ]]; then echo "TAG=PG14_latest" >> $GITHUB_ENV fi diff --git a/drivers/docker-compose.yml b/drivers/docker-compose.yml index 095d72565..45ab86a39 100644 --- a/drivers/docker-compose.yml +++ b/drivers/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.3" services: db: - image: apache/age:PG14_latest + image: apache/age:${TAG} environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=agens From 975f13f29c15065b514cc1b133d998cbea63beab Mon Sep 17 00:00:00 2001 From: Shoaib Date: Wed, 26 Jul 2023 12:01:08 +0200 Subject: [PATCH 8/8] Initial PG15 version Contributors Panagiotis Foliadis Matheus Farias Mohamed Mokhtar Hannan Aamir --- .github/workflows/go-driver.yml | 12 ++-- .github/workflows/installcheck.yaml | 30 ++++----- .github/workflows/jdbc-driver.yaml | 12 ++-- .github/workflows/nodejs-driver.yaml | 12 ++-- .github/workflows/python-driver.yaml | 12 ++-- README.md | 2 +- RELEASE | 2 +- docker/Dockerfile | 4 +- docker/Dockerfile.dev | 2 +- src/backend/catalog/ag_catalog.c | 4 +- src/backend/commands/graph_commands.c | 4 +- src/backend/commands/label_commands.c | 12 ++-- src/backend/executor/cypher_delete.c | 4 +- src/backend/parser/cypher_analyze.c | 2 +- src/backend/parser/cypher_clause.c | 53 ++++++++-------- src/backend/parser/cypher_expr.c | 39 +++++++----- src/backend/parser/cypher_gram.y | 88 +++++++++++++-------------- src/backend/utils/adt/agtype.c | 24 +++++--- src/include/nodes/cypher_nodes.h | 2 +- 19 files changed, 165 insertions(+), 155 deletions(-) diff --git a/.github/workflows/go-driver.yml b/.github/workflows/go-driver.yml index d9f69a5e9..adbacc93b 100644 --- a/.github/workflows/go-driver.yml +++ b/.github/workflows/go-driver.yml @@ -2,10 +2,10 @@ name: Go Driver Tests on: push: - branches: [ "master", "PG14" ] + branches: [ "master", "PG15" ] pull_request: - branches: [ "master", "PG14" ] + branches: [ "master", "PG15" ] jobs: build: @@ -26,14 +26,14 @@ jobs: if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then if [[ "$GITHUB_REF" == "refs/heads/master" ]]; then echo "TAG=latest" >> $GITHUB_ENV - elif [[ "$GITHUB_REF" == "refs/heads/PG14" ]]; then - echo "TAG=PG14_latest" >> $GITHUB_ENV + elif [[ "$GITHUB_REF" == "refs/heads/PG15" ]]; then + echo "TAG=PG15_latest" >> $GITHUB_ENV fi elif [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then if [[ "$GITHUB_BASE_REF" == "master" ]]; then echo "TAG=latest" >> $GITHUB_ENV - elif [[ "$GITHUB_BASE_REF" == "PG14" ]]; then - echo "TAG=PG14_latest" >> $GITHUB_ENV + elif [[ "$GITHUB_BASE_REF" == "PG15" ]]; then + echo "TAG=PG15_latest" >> $GITHUB_ENV fi fi diff --git a/.github/workflows/installcheck.yaml b/.github/workflows/installcheck.yaml index 9e8314945..3709c9744 100644 --- a/.github/workflows/installcheck.yaml +++ b/.github/workflows/installcheck.yaml @@ -2,32 +2,32 @@ name: Build / Regression on: push: - branches: [ 'master', 'PG14' ] + branches: [ 'master', 'PG15' ] pull_request: - branches: [ 'master', 'PG14' ] + branches: [ 'master', 'PG15' ] jobs: build: runs-on: ubuntu-latest steps: - - name: Get latest commit id of PostgreSQL 14 + - name: Get latest commit id of PostgreSQL 15 run: | - echo "PG_COMMIT_HASH=$(git ls-remote git://git.postgresql.org/git/postgresql.git refs/heads/REL_14_STABLE | awk '{print $1}')" >> $GITHUB_ENV + echo "PG_COMMIT_HASH=$(git ls-remote git://git.postgresql.org/git/postgresql.git refs/heads/REL_15_STABLE | awk '{print $1}')" >> $GITHUB_ENV - - name: Cache PostgreSQL 14 + - name: Cache PostgreSQL 15 uses: actions/cache@v3 - id: pg14cache + id: pg15cache with: - path: ~/pg14 - key: ${{ runner.os }}-v1-pg14-${{ env.PG_COMMIT_HASH }} + path: ~/pg15 + key: ${{ runner.os }}-v1-pg15-${{ env.PG_COMMIT_HASH }} - - name: Install PostgreSQL 14 - if: steps.pg14cache.outputs.cache-hit != 'true' + - name: Install PostgreSQL 15 + if: steps.pg15cache.outputs.cache-hit != 'true' run: | - git clone --depth 1 --branch REL_14_STABLE git://git.postgresql.org/git/postgresql.git ~/pg14source - cd ~/pg14source - ./configure --prefix=$HOME/pg14 CFLAGS="-std=gnu99 -ggdb -O0" --enable-cassert + git clone --depth 1 --branch REL_15_STABLE git://git.postgresql.org/git/postgresql.git ~/pg15source + cd ~/pg15source + ./configure --prefix=$HOME/pg15 CFLAGS="-std=gnu99 -ggdb -O0" --enable-cassert make install -j$(nproc) > /dev/null - uses: actions/checkout@v3 @@ -35,12 +35,12 @@ jobs: - name: Build id: build run: | - make PG_CONFIG=$HOME/pg14/bin/pg_config install -j$(nproc) + make PG_CONFIG=$HOME/pg15/bin/pg_config install -j$(nproc) - name: Regression tests id: regression_tests run: | - make PG_CONFIG=$HOME/pg14/bin/pg_config installcheck + make PG_CONFIG=$HOME/pg15/bin/pg_config installcheck continue-on-error: true - name: Dump regression test errors diff --git a/.github/workflows/jdbc-driver.yaml b/.github/workflows/jdbc-driver.yaml index 9be72f8cc..7dda51a4e 100644 --- a/.github/workflows/jdbc-driver.yaml +++ b/.github/workflows/jdbc-driver.yaml @@ -2,10 +2,10 @@ name: JDBC Driver Tests on: push: - branches: [ "master", "PG14" ] + branches: [ "master", "PG15" ] pull_request: - branches: [ "master", "PG14" ] + branches: [ "master", "PG15" ] jobs: build: @@ -28,14 +28,14 @@ jobs: if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then if [[ "$GITHUB_REF" == "refs/heads/master" ]]; then echo "TAG=latest" >> $GITHUB_ENV - elif [[ "$GITHUB_REF" == "refs/heads/PG14" ]]; then - echo "TAG=PG14_latest" >> $GITHUB_ENV + elif [[ "$GITHUB_REF" == "refs/heads/PG15" ]]; then + echo "TAG=PG15_latest" >> $GITHUB_ENV fi elif [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then if [[ "$GITHUB_BASE_REF" == "master" ]]; then echo "TAG=latest" >> $GITHUB_ENV - elif [[ "$GITHUB_BASE_REF" == "PG14" ]]; then - echo "TAG=PG14_latest" >> $GITHUB_ENV + elif [[ "$GITHUB_BASE_REF" == "PG15" ]]; then + echo "TAG=PG15_latest" >> $GITHUB_ENV fi fi diff --git a/.github/workflows/nodejs-driver.yaml b/.github/workflows/nodejs-driver.yaml index 78303591b..36356a7c3 100644 --- a/.github/workflows/nodejs-driver.yaml +++ b/.github/workflows/nodejs-driver.yaml @@ -2,10 +2,10 @@ name: Nodejs Driver Tests on: push: - branches: [ "master", "PG14" ] + branches: [ "master", "PG15" ] pull_request: - branches: [ "master", "PG14" ] + branches: [ "master", "PG15" ] jobs: build: @@ -23,14 +23,14 @@ jobs: if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then if [[ "$GITHUB_REF" == "refs/heads/master" ]]; then echo "TAG=latest" >> $GITHUB_ENV - elif [[ "$GITHUB_REF" == "refs/heads/PG14" ]]; then - echo "TAG=PG14_latest" >> $GITHUB_ENV + elif [[ "$GITHUB_REF" == "refs/heads/PG15" ]]; then + echo "TAG=PG15_latest" >> $GITHUB_ENV fi elif [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then if [[ "$GITHUB_BASE_REF" == "master" ]]; then echo "TAG=latest" >> $GITHUB_ENV - elif [[ "$GITHUB_BASE_REF" == "PG14" ]]; then - echo "TAG=PG14_latest" >> $GITHUB_ENV + elif [[ "$GITHUB_BASE_REF" == "PG15" ]]; then + echo "TAG=PG15_latest" >> $GITHUB_ENV fi fi diff --git a/.github/workflows/python-driver.yaml b/.github/workflows/python-driver.yaml index 2bb6206f7..9a7f3559a 100644 --- a/.github/workflows/python-driver.yaml +++ b/.github/workflows/python-driver.yaml @@ -2,10 +2,10 @@ name: Python Driver Tests on: push: - branches: [ "master", "PG14" ] + branches: [ "master", "PG15" ] pull_request: - branches: [ "master", "PG14" ] + branches: [ "master", "PG15" ] jobs: build: @@ -23,14 +23,14 @@ jobs: if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then if [[ "$GITHUB_REF" == "refs/heads/master" ]]; then echo "TAG=latest" >> $GITHUB_ENV - elif [[ "$GITHUB_REF" == "refs/heads/PG14" ]]; then - echo "TAG=PG14_latest" >> $GITHUB_ENV + elif [[ "$GITHUB_REF" == "refs/heads/PG15" ]]; then + echo "TAG=PG15_latest" >> $GITHUB_ENV fi elif [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then if [[ "$GITHUB_BASE_REF" == "master" ]]; then echo "TAG=latest" >> $GITHUB_ENV - elif [[ "$GITHUB_BASE_REF" == "PG14" ]]; then - echo "TAG=PG14_latest" >> $GITHUB_ENV + elif [[ "$GITHUB_BASE_REF" == "PG15" ]]; then + echo "TAG=PG15_latest" >> $GITHUB_ENV fi fi diff --git a/README.md b/README.md index 60b3347cb..821b968a4 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@   - +   diff --git a/RELEASE b/RELEASE index 329a93076..66da63878 100644 --- a/RELEASE +++ b/RELEASE @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -Release Notes for Apache AGE release 0.0.0 for PG 14 +Release Notes for Apache AGE release 0.0.0 for PG 15 Apache AGE 0.0.0 - Release Notes diff --git a/docker/Dockerfile b/docker/Dockerfile index ac9803d5d..45298538e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -16,14 +16,14 @@ # limitations under the License. # -FROM postgres:14 +FROM postgres:15 RUN apt-get update \ && apt-get install -y --no-install-recommends --no-install-suggests \ bison \ build-essential \ flex \ - postgresql-server-dev-14 \ + postgresql-server-dev-15 \ locales ENV LANG=en_US.UTF-8 diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index 8162f5b56..8d5c0000c 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -24,7 +24,7 @@ RUN apt-get install --assume-yes --no-install-recommends --no-install-suggests \ bison \ build-essential \ flex \ - postgresql-server-dev-14 \ + postgresql-server-dev-15 \ locales ENV LANG=en_US.UTF-8 diff --git a/src/backend/catalog/ag_catalog.c b/src/backend/catalog/ag_catalog.c index f7ed249ce..60a576a9e 100644 --- a/src/backend/catalog/ag_catalog.c +++ b/src/backend/catalog/ag_catalog.c @@ -137,8 +137,8 @@ static bool is_age_drop(PlannedStmt *pstmt) if (IsA(obj, String)) { - Value *val = (Value *)obj; - char *str = val->val.str; + String *val = (String *)obj; + char *str = val->sval; if (!pg_strcasecmp(str, "age")) return true; diff --git a/src/backend/commands/graph_commands.c b/src/backend/commands/graph_commands.c index 7df40b948..2d70e65a5 100644 --- a/src/backend/commands/graph_commands.c +++ b/src/backend/commands/graph_commands.c @@ -148,7 +148,7 @@ static Oid create_schema_for_graph(const Name graph_name) integer = SystemTypeName("int4"); data_type = makeDefElem("as", (Node *)integer, -1); maxvalue = makeDefElem("maxvalue", (Node *)makeInteger(LABEL_ID_MAX), -1); - cycle = makeDefElem("cycle", (Node *)makeInteger(true), -1); + cycle = makeDefElem("cycle", (Node *)makeBoolean(true), -1); seq_stmt->options = list_make3(data_type, maxvalue, cycle); seq_stmt->ownerId = InvalidOid; seq_stmt->for_identity = false; @@ -198,7 +198,7 @@ Datum drop_graph(PG_FUNCTION_ARGS) static void drop_schema_for_graph(char *graph_name_str, const bool cascade) { DropStmt *drop_stmt; - Value *schema_name; + String *schema_name; List *label_id_seq_name; DropBehavior behavior; diff --git a/src/backend/commands/label_commands.c b/src/backend/commands/label_commands.c index 6eb991da4..b2e078702 100644 --- a/src/backend/commands/label_commands.c +++ b/src/backend/commands/label_commands.c @@ -516,12 +516,12 @@ static FuncCall *build_id_default_func_expr(char *graph_name, char *label_name, label_id_func_name = list_make2(makeString("ag_catalog"), makeString("_label_id")); graph_name_const = makeNode(A_Const); - graph_name_const->val.type = T_String; - graph_name_const->val.val.str = graph_name; + graph_name_const->val.sval.type = T_String; + graph_name_const->val.sval.sval = graph_name; graph_name_const->location = -1; label_name_const = makeNode(A_Const); - label_name_const->val.type = T_String; - label_name_const->val.val.str = label_name; + label_name_const->val.sval.type = T_String; + label_name_const->val.sval.sval = label_name; label_name_const->location = -1; label_id_func_args = list_make2(graph_name_const, label_name_const); label_id_func = makeFuncCall(label_id_func_name, label_id_func_args, COERCE_SQL_SYNTAX, -1); @@ -530,8 +530,8 @@ static FuncCall *build_id_default_func_expr(char *graph_name, char *label_name, nextval_func_name = SystemFuncName("nextval"); qualified_seq_name = quote_qualified_identifier(schema_name, seq_name); qualified_seq_name_const = makeNode(A_Const); - qualified_seq_name_const->val.type = T_String; - qualified_seq_name_const->val.val.str = qualified_seq_name; + qualified_seq_name_const->val.sval.type = T_String; + qualified_seq_name_const->val.sval.sval = qualified_seq_name; qualified_seq_name_const->location = -1; regclass_cast = makeNode(TypeCast); regclass_cast->typeName = SystemTypeName("regclass"); diff --git a/src/backend/executor/cypher_delete.c b/src/backend/executor/cypher_delete.c index 68fafae77..795d4c0ec 100644 --- a/src/backend/executor/cypher_delete.c +++ b/src/backend/executor/cypher_delete.c @@ -377,13 +377,13 @@ static void process_delete_list(CustomScanState *node) ResultRelInfo *resultRelInfo; HeapTuple heap_tuple; char *label_name; - Value *pos; + Integer *pos; int entity_position; item = lfirst(lc); pos = item->entity_position; - entity_position = pos->val.ival; + entity_position = pos->ival; /* skip if the entity is null */ if (scanTupleSlot->tts_isnull[entity_position - 1]) diff --git a/src/backend/parser/cypher_analyze.c b/src/backend/parser/cypher_analyze.c index ea9a08893..a154960c1 100644 --- a/src/backend/parser/cypher_analyze.c +++ b/src/backend/parser/cypher_analyze.c @@ -768,7 +768,7 @@ static Query *analyze_cypher_and_coerce(List *stmt, RangeTblFunction *rtfunc, addNSItemToQuery(pstate, pnsi, true, true, true); - query->targetList = expandNSItemAttrs(pstate, pnsi, 0, -1); + query->targetList = expandNSItemAttrs(pstate, pnsi, 0, true, -1); markTargetListOrigins(pstate, query->targetList); diff --git a/src/backend/parser/cypher_clause.c b/src/backend/parser/cypher_clause.c index 299f12030..ba74db062 100644 --- a/src/backend/parser/cypher_clause.c +++ b/src/backend/parser/cypher_clause.c @@ -1341,7 +1341,7 @@ static Query *transform_cypher_unwind(cypher_parsestate *cpstate, errmsg("invalid value for rtindex"))); } - query->targetList = expandNSItemAttrs(pstate, pnsi, 0, -1); + query->targetList = expandNSItemAttrs(pstate, pnsi, 0, true, -1); } target_syntax_loc = exprLocation((const Node *) self->target); @@ -1400,7 +1400,8 @@ static List *transform_cypher_delete_item_list(cypher_parsestate *cpstate, { Node *expr = lfirst(lc); ColumnRef *col; - Value *val, *pos; + String *val; + Integer *pos; int resno; cypher_delete_item *item = make_ag_node(cypher_delete_item); @@ -1427,13 +1428,13 @@ static List *transform_cypher_delete_item_list(cypher_parsestate *cpstate, (errmsg_internal("unexpected Node for cypher_clause"))); } - resno = get_target_entry_resno(query->targetList, val->val.str); + resno = get_target_entry_resno(query->targetList, val->sval); if (resno == -1) { ereport(ERROR, (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), errmsg("undefined reference to variable %s in DELETE clause", - val->val.str), + val->sval), parser_errposition(pstate, col->location))); } @@ -1441,7 +1442,7 @@ static List *transform_cypher_delete_item_list(cypher_parsestate *cpstate, pos = makeInteger(resno); - item->var_name = val->val.str; + item->var_name = val->sval; item->entity_position = pos; items = lappend(items, item); @@ -1539,7 +1540,7 @@ cypher_update_information *transform_cypher_remove_item_list( ColumnRef *ref; A_Indirection *ind; char *variable_name, *property_name; - Value *property_node, *variable_node; + String *property_node, *variable_node; item = make_ag_node(cypher_update_item); @@ -1585,7 +1586,7 @@ cypher_update_information *transform_cypher_remove_item_list( variable_node = linitial(ref->fields); - variable_name = variable_node->val.str; + variable_name = variable_node->sval; item->var_name = variable_name; item->entity_position = get_target_entry_resno(query->targetList, @@ -1620,7 +1621,7 @@ cypher_update_information *transform_cypher_remove_item_list( errmsg("REMOVE clause expects a property name"), parser_errposition(pstate, set_item->location))); } - property_name = property_node->val.str; + property_name = property_node->sval; item->prop_name = property_name; info->set_items = lappend(info->set_items, item); @@ -1648,7 +1649,7 @@ cypher_update_information *transform_cypher_set_item_list( ColumnRef *ref; A_Indirection *ind; char *variable_name, *property_name; - Value *property_node, *variable_node; + String *property_node, *variable_node; int is_entire_prop_update = 0; // true if a map is assigned to variable // LHS of set_item must be a variable or an indirection. @@ -1748,7 +1749,7 @@ cypher_update_information *transform_cypher_set_item_list( parser_errposition(pstate, set_item->location))); } - property_name = property_node->val.str; + property_name = property_node->sval; item->prop_name = property_name; } @@ -1762,7 +1763,7 @@ cypher_update_information *transform_cypher_set_item_list( parser_errposition(pstate, set_item->location))); } - variable_name = variable_node->val.str; + variable_name = variable_node->sval; item->var_name = variable_name; item->entity_position = get_target_entry_resno(query->targetList, @@ -2330,7 +2331,7 @@ static Query *transform_cypher_clause_with_where(cypher_parsestate *cpstate, * all the variables that are introduced in the previous clause to the * next clause */ - query->targetList = expandNSItemAttrs(pstate, pnsi, 0, -1); + query->targetList = expandNSItemAttrs(pstate, pnsi, 0, true, -1); markTargetListOrigins(pstate, query->targetList); @@ -2611,7 +2612,7 @@ static Query *transform_cypher_match_pattern(cypher_parsestate *cpstate, * next clause */ pnsi = get_namespace_item(pstate, rte); - query->targetList = expandNSItemAttrs(pstate, pnsi, 0, -1); + query->targetList = expandNSItemAttrs(pstate, pnsi, 0, true, -1); } transform_match_pattern(cpstate, query, self->pattern, where); @@ -3049,7 +3050,7 @@ static FuncCall *prevent_duplicate_edges(cypher_parsestate *cpstate, List *edges = NIL; ListCell *lc; List *qualified_function_name; - Value *ag_catalog, *edge_fn; + String *ag_catalog, *edge_fn; ag_catalog = makeString("ag_catalog"); edge_fn = makeString("_ag_enforce_edge_uniqueness"); @@ -3154,8 +3155,8 @@ static List *make_join_condition_for_edge(cypher_parsestate *cpstate, { Node *left_id = NULL; Node *right_id = NULL; - Value *ag_catalog = makeString("ag_catalog"); - Value *func_name; + String *ag_catalog = makeString("ag_catalog"); + String *func_name; List *qualified_func_name; List *args = NIL; List *quals = NIL; @@ -3205,7 +3206,7 @@ static List *make_join_condition_for_edge(cypher_parsestate *cpstate, prev_edge->type == ENT_VLE_EDGE) { List *qualified_name, *args; - Value *match_qual; + String *match_qual; FuncCall *fc; match_qual = makeString("age_match_two_vle_edges"); @@ -3348,8 +3349,8 @@ static List *make_join_condition_for_edge(cypher_parsestate *cpstate, static Node *make_type_cast_to_agtype(Node *arg) { TypeCast *n = makeNode(TypeCast); - Value *ag_catalog = makeString("ag_catalog"); - Value *agtype_str = makeString("agtype"); + String *ag_catalog = makeString("ag_catalog"); + String *agtype_str = makeString("agtype"); List *qualified_name = list_make2(ag_catalog, agtype_str); n->arg = arg; @@ -3366,8 +3367,8 @@ static Node *make_bool_a_const(bool state) { A_Const *n = makeNode(A_Const); - n->val.type = T_String; - n->val.val.str = (state ? "true" : "false"); + n->val.sval.type = T_String; + n->val.sval.sval = (state ? "true" : "false"); n->location = -1; // typecast to agtype @@ -3416,7 +3417,7 @@ static List *join_to_entity(cypher_parsestate *cpstate, else if (entity->type == ENT_VLE_EDGE) { List *qualified_name, *args; - Value *ag_catalog, *match_qual; + String *ag_catalog, *match_qual; bool is_left_side; FuncCall *fc; @@ -3539,12 +3540,12 @@ static A_Expr *filter_vertices_on_label_id(cypher_parsestate *cpstate, cpstate->graph_oid); A_Const *n; FuncCall *fc; - Value *ag_catalog, *extract_label_id; + String *ag_catalog, *extract_label_id; int32 label_id = lcd->id; n = makeNode(A_Const); - n->val.type = T_Integer; - n->val.val.ival = label_id; + n->val.ival.type = T_Integer; + n->val.ival.ival = label_id; n->location = -1; ag_catalog = makeString("ag_catalog"); @@ -6803,7 +6804,7 @@ static void handle_prev_clause(cypher_parsestate *cpstate, Query *query, } // add all the rte's attributes to the current queries targetlist - query->targetList = expandNSItemAttrs(pstate, pnsi, 0, -1); + query->targetList = expandNSItemAttrs(pstate, pnsi, 0, true, -1); } ParseNamespaceItem *find_pnsi(cypher_parsestate *cpstate, char *varname) diff --git a/src/backend/parser/cypher_expr.c b/src/backend/parser/cypher_expr.c index a54652303..646ac9e2f 100644 --- a/src/backend/parser/cypher_expr.c +++ b/src/backend/parser/cypher_expr.c @@ -42,7 +42,6 @@ #include "parser/parse_relation.h" #include "utils/builtins.h" #include "utils/float.h" -#include "utils/int8.h" #include "utils/lsyscache.h" #include "utils/syscache.h" @@ -211,23 +210,27 @@ static Node *transform_A_Const(cypher_parsestate *cpstate, A_Const *ac) { ParseState *pstate = (ParseState *)cpstate; ParseCallbackState pcbstate; - Value *v = &ac->val; + Datum d = (Datum)0; bool is_null = false; Const *c; setup_parser_errposition_callback(&pcbstate, pstate, ac->location); - switch (nodeTag(v)) + switch (nodeTag(&ac->val)) { case T_Integer: - d = integer_to_agtype((int64)intVal(v)); + d = integer_to_agtype((int64)intVal(&ac->val)); break; case T_Float: { - char *n = strVal(v); + char *n = ac->val.sval.sval; + char *endptr; int64 i; + errno = 0; + + i = strtoi64(ac->val.fval.fval, &endptr, 10); - if (scanint8(n, true, &i)) + if (errno == 0 && *endptr == '\0') { d = integer_to_agtype(i); } @@ -240,15 +243,19 @@ static Node *transform_A_Const(cypher_parsestate *cpstate, A_Const *ac) } break; case T_String: - d = string_to_agtype(strVal(v)); + d = string_to_agtype(strVal(&ac->val)); break; - case T_Null: - is_null = true; + case T_Boolean: + d = boolean_to_agtype(boolVal(&ac->val)); break; default: - ereport(ERROR, - (errmsg_internal("unrecognized node type: %d", nodeTag(v)))); - return NULL; + if (ac->isnull) { + is_null = true; + } else { + ereport(ERROR, + (errmsg_internal("unrecognized node type: %d", nodeTag(&ac->val)))); + return NULL; + } } cancel_parser_errposition_callback(&pcbstate); @@ -865,7 +872,7 @@ static Node *transform_A_Indirection(cypher_parsestate *cpstate, if (!indices->lidx) { A_Const *n = makeNode(A_Const); - n->val.type = T_Null; + n->isnull = true; n->location = -1; node = transform_cypher_expr_recurse(cpstate, (Node *)n); } @@ -879,7 +886,7 @@ static Node *transform_A_Indirection(cypher_parsestate *cpstate, if (!indices->uidx) { A_Const *n = makeNode(A_Const); - n->val.type = T_Null; + n->isnull = true; n->location = -1; node = transform_cypher_expr_recurse(cpstate, (Node *)n); } @@ -1092,7 +1099,7 @@ static Node *transform_FuncCall(cypher_parsestate *cpstate, FuncCall *fn) if (list_length(fn->funcname) == 1) { /* get the name, size, and the ag name allocated */ - char *name = ((Value*)linitial(fn->funcname))->val.str; + char *name = ((String*)linitial(fn->funcname))->sval; int pnlen = strlen(name); char *ag_name = palloc(pnlen + 5); int i; @@ -1286,7 +1293,7 @@ static Node *transform_CaseExpr(cypher_parsestate *cpstate, CaseExpr { A_Const *n = makeNode(A_Const); - n->val.type = T_Null; + n->isnull = true; n->location = -1; defresult = (Node *) n; } diff --git a/src/backend/parser/cypher_gram.y b/src/backend/parser/cypher_gram.y index 26908122c..846e02010 100644 --- a/src/backend/parser/cypher_gram.y +++ b/src/backend/parser/cypher_gram.y @@ -200,7 +200,7 @@ static Node *make_not_expr(Node *expr, int location); // arithmetic operators static Node *do_negate(Node *n, int location); -static void do_negate_float(Value *v); +static void do_negate_float(Float *v); // indirection static Node *append_indirection(Node *expr, Node *selector); @@ -349,7 +349,7 @@ call_stmt: FuncCall *fc = (FuncCall*)$4; ColumnRef *cr = (ColumnRef*)$2; List *fields = cr->fields; - Value *string = linitial(fields); + String *string = linitial(fields); /* * A function can only be qualified with a single schema. So, we @@ -396,7 +396,7 @@ call_stmt: FuncCall *fc = (FuncCall*)$4; ColumnRef *cr = (ColumnRef*)$2; List *fields = cr->fields; - Value *string = linitial(fields); + String *string = linitial(fields); /* * A function can only be qualified with a single schema. So, we @@ -584,7 +584,7 @@ cypher_varlen_opt: A_Const *lidx = (A_Const *) n->lidx; A_Const *uidx = (A_Const *) n->uidx; - if (lidx->val.val.ival > uidx->val.val.ival) + if (lidx->val.ival.ival > uidx->val.ival.ival) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("invalid range"), ag_scanner_errposition(@2, scanner))); @@ -1466,7 +1466,7 @@ expr: { ColumnRef *cr = (ColumnRef*)$3; List *fields = cr->fields; - Value *string = linitial(fields); + String *string = linitial(fields); $$ = append_indirection($1, (Node*)string); } @@ -1481,7 +1481,7 @@ expr: FuncCall *fc = (FuncCall*)$3; ColumnRef *cr = (ColumnRef*)$1; List *fields = cr->fields; - Value *string = linitial(fields); + String *string = linitial(fields); /* * A function can only be qualified with a single schema. So, we @@ -1505,7 +1505,7 @@ expr: { ColumnRef *cr = (ColumnRef*)$3; List *fields = cr->fields; - Value *string = linitial(fields); + String *string = linitial(fields); $$ = append_indirection($1, (Node*)string); } @@ -2008,14 +2008,14 @@ static Node *do_negate(Node *n, int location) // report the constant's location as that of the '-' sign c->location = location; - if (c->val.type == T_Integer) + if (c->val.ival.type == T_Integer) { - c->val.val.ival = -c->val.val.ival; + c->val.ival.ival = -c->val.ival.ival; return n; } - else if (c->val.type == T_Float) + else if (c->val.fval.type == T_Float) { - do_negate_float(&c->val); + do_negate_float(&c->val.fval); return n; } } @@ -2023,14 +2023,16 @@ static Node *do_negate(Node *n, int location) return (Node *)makeSimpleA_Expr(AEXPR_OP, "-", NULL, n, location); } -static void do_negate_float(Value *v) +static void do_negate_float(Float *v) { - Assert(IsA(v, Float)); - - if (v->val.str[0] == '-') - v->val.str = v->val.str + 1; // just strip the '-' - else - v->val.str = psprintf("-%s", v->val.str); + char *oldval = v->fval; + + if (*oldval == '+') + oldval++; + if (*oldval == '-') + v->fval = oldval+1; /* just strip the '-' */ + else + v->fval = psprintf("-%s", oldval); } /* @@ -2064,60 +2066,56 @@ static Node *append_indirection(Node *expr, Node *selector) static Node *make_int_const(int i, int location) { - A_Const *n; + A_Const *n = makeNode(A_Const); - n = makeNode(A_Const); - n->val.type = T_Integer; - n->val.val.ival = i; + n->val.ival.type = T_Integer; + n->val.ival.ival = i; n->location = location; - return (Node *)n; + return (Node *) n; } static Node *make_float_const(char *s, int location) { - A_Const *n; + A_Const *n = makeNode(A_Const); - n = makeNode(A_Const); - n->val.type = T_Float; - n->val.val.str = s; + n->val.fval.type = T_Float; + n->val.fval.fval = s; n->location = location; - return (Node *)n; + return (Node *) n; } static Node *make_string_const(char *s, int location) { - A_Const *n; + A_Const *n = makeNode(A_Const); - n = makeNode(A_Const); - n->val.type = T_String; - n->val.val.str = s; + n->val.sval.type = T_String; + n->val.sval.sval = s; n->location = location; - return (Node *)n; + return (Node *) n; } static Node *make_bool_const(bool b, int location) { - cypher_bool_const *n; + A_Const *n = makeNode(A_Const); - n = make_ag_node(cypher_bool_const); - n->boolean = b; + n->val.boolval.type = T_Boolean; + n->val.boolval.boolval = b; n->location = location; - return (Node *)n; + return (Node *) n; } static Node *make_null_const(int location) { - A_Const *n; - - n = makeNode(A_Const); - n->val.type = T_Null; + A_Const *n = makeNode(A_Const); + + n->isnull = true; n->location = location; - return (Node *)n; + return (Node *) n; } /* @@ -2149,7 +2147,7 @@ static Node *make_function_expr(List *func_name, List *exprs, int location) char *name; /* get the name of the function */ - name = ((Value*)linitial(func_name))->val.str; + name = ((String*)linitial(func_name))->sval; /* * Check for openCypher functions that are directly mapped to PG @@ -2247,7 +2245,7 @@ static Node *make_set_op(SetOperation op, bool all_or_distinct, List *larg, /* check if A_Expr is a comparison expression */ static bool is_A_Expr_a_comparison_operation(A_Expr *a) { - Value *v = NULL; + String *v = NULL; char *opr_name = NULL; /* we don't support qualified comparison operators */ @@ -2263,7 +2261,7 @@ static bool is_A_Expr_a_comparison_operation(A_Expr *a) Assert(v->type == T_String); /* get the string value */ - opr_name = v->val.str; + opr_name = v->sval; /* verify it is a comparison operation */ if (strcmp(opr_name, "<") == 0) diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c index c95419225..242a951e2 100644 --- a/src/backend/utils/adt/agtype.c +++ b/src/backend/utils/adt/agtype.c @@ -54,7 +54,6 @@ #include "utils/builtins.h" #include "utils/float.h" #include "utils/fmgroids.h" -#include "utils/int8.h" #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/snapmgr.h" @@ -959,7 +958,7 @@ static void agtype_in_scalar(void *pstate, char *token, case AGTYPE_TOKEN_INTEGER: Assert(token != NULL); v.type = AGTV_INTEGER; - scanint8(token, false, &v.val.int_value); + v.val.int_value = pg_strtoint64(token); break; case AGTYPE_TOKEN_FLOAT: Assert(token != NULL); @@ -5515,6 +5514,7 @@ Datum age_tointeger(PG_FUNCTION_ARGS) } else if (type == CSTRINGOID || type == TEXTOID) { + char *endptr; if (type == CSTRINGOID) { string = DatumGetCString(arg); @@ -5525,14 +5525,18 @@ Datum age_tointeger(PG_FUNCTION_ARGS) } /* convert it if it is a regular integer string */ - is_valid = scanint8(string, true, &result); + result = strtoi64(string, &endptr, 10); + /* * If it isn't an integer string, try converting it as a float * string. */ - if (!is_valid) + result = float8in_internal_null(string, NULL, "double precision", + string, &is_valid); + + if (*endptr != '\0') { - float8 f; + float f; f = float8in_internal_null(string, NULL, "double precision", string, &is_valid); @@ -5541,10 +5545,8 @@ Datum age_tointeger(PG_FUNCTION_ARGS) * return null. */ if (!is_valid || isnan(f) || isinf(f) || - f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) - { + f < PG_INT64_MIN || f > (double)PG_INT64_MAX) PG_RETURN_NULL(); - } result = (int64) f; } @@ -5602,16 +5604,18 @@ Datum age_tointeger(PG_FUNCTION_ARGS) } else if (agtv_value->type == AGTV_STRING) { + char *endptr; /* we need a null terminated cstring */ string = strndup(agtv_value->val.string.val, agtv_value->val.string.len); /* convert it if it is a regular integer string */ - is_valid = scanint8(string, true, &result); + result = strtoi64(string, &endptr, 10); + /* * If it isn't an integer string, try converting it as a float * string. */ - if (!is_valid) + if (*endptr != '\0') { float8 f; diff --git a/src/include/nodes/cypher_nodes.h b/src/include/nodes/cypher_nodes.h index 64318eb5d..0b2f65349 100644 --- a/src/include/nodes/cypher_nodes.h +++ b/src/include/nodes/cypher_nodes.h @@ -393,7 +393,7 @@ typedef struct cypher_delete_information typedef struct cypher_delete_item { ExtensibleNode extensible; - Value *entity_position; + Integer *entity_position; char *var_name; } cypher_delete_item;